There is a nav link on my navbar named Login (I have used bootstrap navbar). After successful login I want to replace Login with a username using react-redux (not redux-toolkit). Kindly help me in writing reducer and action code. As I am a beginner in redux and I don't know how to code in reducer and action file it is very confusing for me.
Navbar component (Navbar.js)
import React from 'react';
import { Link } from 'react-router-dom';
import { useSelector } from 'react-redux';
const Navbar = () => {
const {username} = useSelector((state) => state.user);
return (
<div>
<nav className="navbar navbar-expand-lg">
<div className="container-fluid">
<Link className="navbar-brand" to="/hommepage">Ebuy</Link>
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria- expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon">
<i className="fas fa-bars" style={{color: 'white', fontSize: '28px'}}></i>
</span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav me-auto mb-2 mb-lg-0">
<li className="nav-item">
<Link className="nav-link" aria-current="page" to="/homepage">Home</Link>
</li>
<li className="nav-item dropdown">
<Link className="nav-link dropdown-toggle" to="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Select Category
</Link>
<ul className="dropdown-menu" aria-labelledby="navbarDropdown">
<li><Link className="dropdown-item" to="/skincare">Skincare Products</Link></li>
<li><Link className="dropdown-item" to="/stationary">Stationary Products</Link></li>
<li><Link className="dropdown-item" to="#">Clothing</Link></li>
</ul>
</li>
</ul>
<div className="d-flex">
<ul className="navbar-nav me-auto mb-2 mb-lg-0">
<li className='nav-item'>
<Link className="nav-link" to="/">Login</Link>
</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
);
};
export default Navbar;
Login component (Login.js)
import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
import {changeUserName, logged} from '../actions/index';
const Login = () => {
const [name, setName] = useState('');
const [password, setPassword] = useState('');
const dispatch = useDispatch();
let history = useHistory();
const handleClick = () => history.push('/signup');
function handleLogin(e) {
e.preventDefault();
if (document.getElementById('inputusername').value && document.getElementById('inputpassword').value != '') {
history.push('/homepage');
dispatch(changeUserName(name));
}
}
return (
<div className="col-12 signup-container">
<div className="login d-flex align-items-center py-5">
<div className="animate__animated animate__pulse container">
<div className="row">
<div className="col-7 mx-auto formbody">
<h6 className="display-4">Account Login</h6>
<form>
<div className="form-row form-floating mb-2">
<input
type="text"
className="form-control"
id="inputusername"
placeholder="Enter your username"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
<label htmlFor="inputusername">Enter Username</label>
</div>
<div className="form-row form-floating mb-2">
<input
type="password"
className="form-control"
id="inputpassword"
placeholder="Enter your password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
<label htmlFor="inputpassword">Enter Password</label>
</div>
<button
type="submit"
className="w-100 btn btn-primary btn-lg mt-2 login-btn"
value="Click"
onClick={handleLogin}
>
Login
</button>
<div className="goto-signup mt-3">
<p className='mb-0'>
Don't have an account?
</p>
<button type="button" className="btn btn-link" onClick={handleClick}>Create one!</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
};
Login.propTypes = {
setIsAuth: PropTypes.func
};
export default Login;
Reducer (user.js)
const initialState = {
username: null,
};
const userReducer = (state = initialState, action) => {
switch (action.type) {
case 'CHANGE_USERNAME':
return {
...state,
username: action.payload,
};
default:
return state;
}
};
export default userReducer;
Action (index.js)
export const changeUserName = (name) => {
return {
type: 'CHANGE_USERNAME',
payload: name
};
};
CodePudding user response:
reducer
const initialState = {
username: null,
}
export const userReducer(state = initialState, action) {
switch (action.type) {
case "CHANGE_USERNAME":
return {
...state,
username: action.payload,
}
default:
return state
}
}
action
export const changeUserName = (name) => {
return {
type: "CHANGE_USERNAME",
payload: name
}
}
after login call this
const dispatch = useDispatch()
const login = () => {
... login logic here
dispatch(changeUserName("user-1"))
}
in navbar
const { username } = useSelector(state=> state.user)
CodePudding user response:
In your Navbar Component you should get username from redux, please try this :
const {username} = useSelector(state=> state.yourReducerName)
after this, in your jsx : you should write a condition like this :
{username ? (<div>{username}</div>): ()<span>Login</span>}
EDIT :
Please refer to this sandbox example and take a look on the reducer and actions files, also on the navbar components. Let us know if the post helped you :)
