So, I'm having an issue with redux not keeping state of a 'token' value. Upon vising the app you are directed to a login page. Submitting your login details returns an auth token, which assigns the value of the returned token value to the variable token, adds token to props, and then redirects you to the main part of the app '/'.
If I immediately return to the login page '/login' the token disappears from props, causing a user to have to re-login again.
What is the issue here?
app.js
render(
<ApolloProvider store={store} client={client}>
{ /* Tell the Router to use our enhanced history */ }
<Router history={history}>
<Route path="/" component={App}>
<IndexRoute component={PhotoGrid} />
<Route path="/view/:postId" component={Single}></Route>
<Route path="/login" component={LoginUser}></Route>
</Route>
</Router>
</ApolloProvider>,
document.getElementById('root')
);
App.js
function mapStateToProps(state) {
return {
token: state.token[0]
};
}
Root reducer (index.js)
import { combineReducers } from 'redux';
import client from '../apolloClient';
import { routerReducer } from 'react-router-redux'; // we need this for react-router
import tokenDetails from './tokenDetails';
const rootReducer = combineReducers({
token: tokenDetails,
routing: routerReducer,
apollo: client.reducer(),
});
export default rootReducer;
tokenDetails.js
var tokenDetails = function(state, action) {
if (state === undefined) {
state = [];
}
switch (action.type) {
case 'Graphcool_Token':
const newState = [action.payload];
return newState;
default:
return state;
}
}
export default tokenDetails;
actionCreator,js
export function authToken(token) {
return (dispatch) => {
dispatch({
type: 'Graphcool_Token',
payload: token
});
}
}
LoginUser.js
signinUser: function(emailID, passwordID) {
const email = emailID;
const password = passwordID;
this.props.client.mutate({
mutation: signinUser_Mutation,
variables: {
email,
password,
},
options: {
cachePolicy: 'offline-critical',
fetchPolicy: 'cache-first',
},
})
.then(this.updateStateLoginDetails)
.catch(this.handleSubmitError);
},
updateStateLoginDetails: function({data}) {
this.props.authToken(data.signinUser.token);
this.context.router.push('/');
},
handleSubmitError: function(err) {
console.error(err.message);
},
handleSubmit: function(e) {
e.preventDefault();
this.signinUser(this.refs.email.value, this.refs.password.value);
this.refs.loginForm.reset();
this.refs.email.focus();
},
render: function() {
}
store.js
const middlewares = [thunk, client.middleware()];
const enhancers = compose(
applyMiddleware(...middlewares),
(typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' || process.env.NODE_ENV !== 'production') ? window.__REDUX_DEVTOOLS_EXTENSION__() : (f) => f,
autoRehydrate(),
);
const store = createStore(
rootReducer,
{}, // initial state
enhancers
);
// begin periodically persisting the store
persistStore(store, {storage: localForage});
export const history = syncHistoryWithStore(
browserHistory,
store
);
if(module.hot) {
module.hot.accept('./reducers/', () => {
const nextRootReducer = require('./reducers/index').default;
store.replaceReducer(nextRootReducer);
});
}
export default store;