Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Redux state lost after refresh

I'm really new to React and Redux, I've been following Stephen Grider's Advanced React and Redux course and I'm doing the client side of the authentication. I already have a token saved on my local storage and everything seemed to work fine until I refreshed the page. When I sign in/sign up the navigation changes to display the log out button but then if I manually refresh the page the navigation changes back to display the sign in/sign up buttons.

I'm really new to this and have no idea what should I include as code snippets. I'll leave the reducer and the actions/index.js. Also this is a lik for my git repository.

actions/index.js

import axios from 'axios'; import { browserHistory } from 'react-router'; import { push } from 'react-router-redux'; import { AUTH_USER, UNAUTH_USER, AUTH_ERROR } from './types';  const API_URL = 'http://localhost:3000';  export function signinUser({ username, password }) {   return function(dispatch) {     // Submit username/password to the server     axios       .post(`${API_URL}/signin`, { username, password })       .then(response => {         // If request is good...         // - Update state o indicate user is authenticated         dispatch({ type: AUTH_USER });         // - Save the JWT token to local storage         localStorage.setItem('token', response.data.token);         // - Redirect to the route '/feature'         browserHistory.push('/feature');       })       .catch(() => {         // If request is bad...         // -Show an error to the user         dispatch(authError('Bad login info'));       });   }; }  export function signupUser({ username, email, password }) {   return function(dispatch) {     axios       .post(`${API_URL}/signup`, { username, email, password })       .then(response => {         dispatch({ type: AUTH_USER });         localStorage.setItem('token', response.data.token);         browserHistory.push('/feature');       })       .catch(response => {         // TODO         console.log(response);         dispatch(authError('There was an error'));       });   }; }  export function authError(error) {   return {     type: AUTH_ERROR,     payload: error   }; }  export function signoutUser() {   localStorage.removeItem('token');   return { type: UNAUTH_USER }; } 

reducer/auth_reducer.js

import { AUTH_USER, UNAUTH_USER, AUTH_ERROR } from '../actions/types'; export default function(state = {}, action) {   switch (action.type) {     case AUTH_USER:       return { ...state, error: '', authenticated: true };     case UNAUTH_USER:       return { ...state, authenticated: false };     case AUTH_ERROR:       return { ...state, error: action.payload };   }    return state; } 

Thanks in advance, if you need any extra code snippet just please let me know.

like image 745
OmarAguinaga Avatar asked Oct 10 '17 18:10

OmarAguinaga


People also ask

Does Redux keep state after refresh?

With the Redux Persist library, developers can save the Redux store in persistent storage, for example, the local storage. Therefore, even after refreshing the browser, the site state will still be preserved.

How do I save Redux state after refresh?

If you would like to persist your redux state across a browser refresh, it's best to do this using redux middleware. Check out the redux-persist and redux-storage middleware. They both try to accomplish the same task of storing your redux state so that it may be saved and loaded at will.

Is state lost on refresh?

To be clear: all state is lost when you refresh the page; anything you want saved has to be manually saved and restored. Possible duplicate of How can I persist redux state tree on refresh?


2 Answers

do not reinvent the wheel

To store redux state even after page refresh you can use

https://www.npmjs.com/package/redux-persist

It is easy to implement and robust.

like image 61
Ashad Nasim Avatar answered Oct 02 '22 15:10

Ashad Nasim


In your reducer file reducer/auth_reducer.js you can define the initial state of the reducer.

const initialState = {  user: localStorage.getItem('user'), foo:'bar', };  export default function(state = initialState, action) {     ... 

in your initialState you can load stuff from localstorage or from a cookie (cookie is preferred for auth stuff).

initialState can also be setup in your createStore. It's up to you. Where you need the initial state. I use async for my routes so I can't use createStore to hold all my initial state since some routes maybe never be loaded.

const initialState = {   user: localStorage.getItem('user'), };  const store = createStore(mainReducer, initialState); 

There is a library you can use called redux-persist. This will give you more control of what state you want to keep. (https://github.com/rt2zz/redux-persist)

like image 34
Richard Torcato Avatar answered Oct 02 '22 17:10

Richard Torcato