Error says that it reads isAuthenticated as undefined, even though in my global state I have the variable under state.authReducer.isAuthenticated.
I'm using redux and it appears that I can't access the global state (I think the issue lies in store.js but I really don't know what exactly is the issue). Some fellow learner has posted a similiar (maybe identical) issue, but the answers did not help me as it still reads isAuthenticated as undefined.
store.js:
const initialState = {};
const middleware = [thunk];
const store = legacy_createStore(
rootReducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;
authReducer:
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: null,
loading: true,
user: null,
};
const authReducer = (state = initialState, action) => {
const { type, payload } = action;
switch (type) {
case LOGIN_SUCCESS:
localStorage.setItem('token', payload.token);
return {
...state,
...payload,
isAuthenticated: true,
loading: false,
};
case LOGIN_FAIL:
localStorage.removeItem('token');
return {
...state,
token: null,
isAuthenticated: false,
loading: false,
};
default:
return state;
}
};
Login.js component:
const Login = ({ loginUser, isAuthenticated }) => {
const [formData, setFormData] = useState({
email: '',
password: '',
});
const { email, password } = formData;
const onChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const onSubmit = async (e) => {
e.preventDefault();
loginUser(email, password);
};
// Redirect if logged in
if (isAuthenticated) {
return <Navigate to='/dashboard' />;
}
return(some JSX form)
Login.propTypes = {
login: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
};
const mapStateToProps = (state) => ({
isAuthenticated: state.auth.isAuthenticated,
});
export default connect(null, { loginUser })(Login);
Edit: I found out that if I set connect() function first parameter to null, the component renders, but if I set the parameter to mapStateToProps it doesn't render (inside the component). Still, my issue is the same: isAuthenticated is undefined.
CodePudding user response:
How are you defining rootReducer
?
My guess, without looking, is that you're either treating all of the auth
reducer as rootReducer
, or calling combineReducers({authReducer})
. In either case, there won't be a state.auth
field, because your store configuration did not define one.
The short fix here is:
const rootReducer = combineReducers({
auth: authReducer
})
The better answer is to use our official Redux Toolkit package and its configureStore
API, instead of the legacy createStore
API:
const store = configureStore({
reducer: {
auth: authReducer
}
})
// this added `state.auth`, _and_ the thunk middleware,
// _and_ the Redux DevTools, in one function call!
You should also be using RTK's createSlice
instead of writing reducers by hand.