I am new to redux and trying to create a small site in which users can: login, register and logout.
I have created 2 reducers for login and registration and I have a "isLoggedIn" field initialized in both reducers' state.
When trying to create a 3rd reducer for logout, adding it to the CombineReducers and then try to login/register, it is not logging me out, it does nothing. The only thing that is working is if I am using only the login and register reducers, and on each reducer I add a 'case LOGOUT'.
However, I feel like there is a better way of doing that since it is duplicating my code on all reducers that needs the logout functionality.
authentication.js (login)
import { userConstants } from "../constants";
const initialState = {
user: {
email: "",
username: "",
},
isLoggedIn: false,
};
export function authentication(state = initialState, action) {
switch (action.type) {
case userConstants.LOGIN_REQUEST:
return Object.assign({}, state, {
isLoggedIn: false,
});
case userConstants.LOGIN_SUCCESS:
return Object.assign({}, state, {
isLoggedIn: true,
user: action.user,
});
case userConstants.LOGIN_FAILURE:
return {};
case userConstants.LOGOUT:
return Object.assign({}, state, {
isLoggedIn: false,
});
default:
return state;
}
}
registration.js
import { userConstants } from "../constants";
export function registration(state = { isLoggedIn: false, user: {} }, action) {
switch (action.type) {
case userConstants.SIGN_UP_REQUEST:
return Object.assign({}, state, {
isLoggedIn: false,
});
case userConstants.SIGN_UP:
return Object.assign({}, state, {
isLoggedIn: true,
user: action.user,
});
case userConstants.SIGN_UP_FAILED:
return {};
case userConstants.LOGOUT:
return Object.assign({}, state, {
isLoggedIn: false,
});
default:
return state;
}
}
reducers/index.js
import { combineReducers } from "redux";
import { authentication } from "./authentication";
import { registration } from "./registration";
const rootReducer = combineReducers({
authentication,
registration,
});
export default rootReducer;
routes/index.js
function mapStateToProps(state) {
return {
isLoggedIn:
state.authentication.isLoggedIn || state.registration.isLoggedIn,
};
}
const mapDispatchToProps = (dispatch) => ({
logout: () => dispatch(logout()),
});
export default connect(mapStateToProps, mapDispatchToProps)(MainNavigation);
store.js
import { createStore, applyMiddleware, compose } from "redux";
import rootReducer from "./reducers";
import thunk from "redux-thunk";
import { createLogger } from "redux-logger";
const logger = createLogger();
const store = createStore(
rootReducer,
compose(applyMiddleware(thunk), applyMiddleware(logger))
);
export default store;
In routes/index.js I am using the "isLoggedIn" field in order to show the user specific pages depends on if he is logged in or not.
The above program is the only solution I was able to achieve.
Also, if it matters, all my actions for logout, login and register are within the same file.