Reputation: 2228
I have a ecommerce store with registration and login. After registration, the token is stored in cookie and authentication state is updated. It is working. But the problem is, when I refresh the page, authentication state is set to null. Please check my store and reducers.
store.js
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(rootReducer, initialState,
composeWithDevTools(applyMiddleware(...middleware)));
export default store;
authReducer.js
import * as types from '../types'
export const authReducer = (state = { token: null }, action) => {
switch (action.type) {
case types.AUTHENTICATE:
return {
...state,
token: action.payload
};
case types.DEAUTHENTICATE:
return {
token: null
};
default:
return state;
}
};
authAction.js
import * as types from '../types'
import axios from 'axios'
import cookie from 'js-cookie';
import * as api from '../../pages/api'
import Router from 'next/router';
export const authenticate = user => async dispatch => {
const res = await axios.post(api.URL_REGISTER, {user})
.then(res => {
if (res.data.response === 200) {
setCookie('token', res.data.data.token);
Router.push('/');
dispatch({
type: types.AUTHENTICATE,
payload: res.data.data.token
})
}
else
dispatch({
type: types.AUTHENTICATE,
payload: res.data
})
}).catch(error => {
console.log(error);
});
}
// gets the token from the cookie and saves it in the store
export const reauthenticate = token => {
return dispatch => {
dispatch({ type: types.AUTHENTICATE, payload: token });
};
};
// removing the token
export const deauthenticate = () => {
return dispatch => {
removeCookie('token');
Router.push('/');
dispatch({ type: types.DEAUTHENTICATE });
};
};
/**
* cookie helper methods
*/
export const setCookie = (key, value) => {
if (process.browser) {
cookie.set(key, value, {
expires: 1,
path: '/'
});
}
};
export const removeCookie = key => {
if (process.browser) {
cookie.remove(key, {
expires: 1
});
}
};
export const getCookie = key => {
return cookie.get(key);
};
Header.js
import React from 'react'
import Link from 'next/link'
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
import { faSearch, faShoppingCart, faUserCircle, faBoxOpen, faHeart } from '@fortawesome/fontawesome-free-solid'
import { deauthenticate } from '../../store/actions/authAction';
import { connect } from 'react-redux';
const Header = ({ deauthenticate, isAuthenticated }) => (
<div>
<div className="col-12 col-md-4 col-lg-3">
<div className="text-center text-md-right">
<div className="d-inline loginDrop">
<Link href="/">
<a className="signinBtn mr-5">{!isAuthenticated ? "Sign In" : "My Account"}</a>
</Link>
<div className={!isAuthenticated ? "login-content" : "login-content logout-content"}>
<p> </p>
<div className="login-inner">
<Link href={!isAuthenticated ? "/login" : "/profile"}><a><FontAwesomeIcon icon={faUserCircle} className="mr-2"/> Your Profile</a></Link>
<Link href={!isAuthenticated ? "/login" : "/orders"}><a><FontAwesomeIcon icon={faBoxOpen} className="mr-2 orderIcon"/> Orders</a></Link>
<Link href={!isAuthenticated ? "/login" : "/wishlist"}><a><FontAwesomeIcon icon={faHeart} className="mr-2"/> Whishlist</a></Link>
<div className="otherDrop">
{!isAuthenticated ?
<>
<p className="first">Don't have an account?</p>
<p className="register"><Link href="/register" as="/register"><a>Register</a></Link></p>
<p className="login"><Link href="/login"><a>Login</a></Link></p>
</>
:
<p className="login"><a href="#" onClick={deauthenticate}>Logout</a></p>
}
</div>
</div>
</div>
</div>
<Link href="/">
<a className="cartBtn"><FontAwesomeIcon icon={faShoppingCart} className="mr-xl-1"/> Cart</a>
</Link>
</div>
</div>
</div>
)
const mapStateToProps = state => ({ isAuthenticated: !!state.authentication.token });
export default connect(
mapStateToProps,
{ deauthenticate }
)(Header);
_app.js
import App from 'next/app'
import React from 'react'
import {Provider} from 'react-redux'
import {createWrapper} from 'next-redux-wrapper'
import store from '../store/store'
class MyApp extends App {
render() {
const {Component, pageProps} = this.props
return (
<Provider store={store}>
<Component {...pageProps}></Component>
</Provider>
)
}
}
const makestore = () => store;
const wrapper = createWrapper(makestore);
export default wrapper.withRedux(MyApp);
How to fix initial state not to be null even after refresh the page. I am really stuck here. Is there any option to fix.
Upvotes: 2
Views: 3248
Reputation: 293
All you need is to persist your redux state across a browser refresh by using redux middleware like redux-persist, ie:
if (isClient) {
store = createStore(
persistReducer(persistConfig, rootReducer),
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
}
Upvotes: 2