Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

on refresh the state value is lost in react.js

Tags:

reactjs

redux

I am getting an state value i.e loggedIn user name then printing loggedIn user name on my page. But when I refresh my page then the state value is lost.

I am creating state value using redux.

This is my action.js -

// Login - get user token
export const loginUser = userData => dispatch => {
  axios
    .post("http://localhost:5000/login", userData)
    .then(res => {
      // Save to localStorage
      // Set token to localStorage
      const { token } = res.data;
      localStorage.setItem("usertoken", token);
      // Set token to Auth header
      setAuthToken(token);
      // Decode token to get user data
      const decoded = jwt_decode(token);
      // Set current user
      dispatch(setCurrentUser(decoded));
    })
    .catch(err => {
      return err;
    }

    );
};
// Set logged in user
export const setCurrentUser = decoded => {
  return {
    type: SET_CURRENT_USER,
    payload: decoded
  };
};
// User loading
export const setUserLoading = () => {
  return {
    type: USER_LOADING
  };
};
// Log user out
export const logoutUser = () => dispatch => {
  // Remove token from local storage
  localStorage.removeItem("usertoken");
  // Remove auth header for future requests
  setAuthToken(false);
  // Set current user to empty object {} which will set isAuthenticated to false
  dispatch(setCurrentUser({}));
};

this is my reducer.js -

import {
  SET_CURRENT_USER,
  USER_LOADING
} from "../Actions/actions";
const isEmpty = require("is-empty");
const initialState = {
  isAuthenticated: false,
  user: {},
  loading: false
};
export default function (state = initialState, action) {
  switch (action.type) {
    case SET_CURRENT_USER:
      return {
        ...state,
        isAuthenticated: !isEmpty(action.payload),
        user: action.payload
      };
    case USER_LOADING:
      return {
        ...state,
        loading: true
      };
    default:
      return state;
  }
}

and in header.js I am printing loggedIn user name.

const userLink = () => (
      <div className="" style={{ display: "inline-flex" }}>
        <li class="nav-item">
          <Link className="nav-link" to="/">
            {user.name}
          </Link>
        </li>
        <li class="nav-item">
          <a href="" onClick={this.logOut.bind(this)} className="nav-link">
            Logout
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="/">
            AboutUs
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="/">
            ContactUs
          </a>
        </li>
      </div>
    );

I am getting loggedIn user name in state. but hen I am refreshing the page the state value of loggedIn user name is lost. One more thing I am including Header.js file in all pages of my react Application.

How can I save my state value of loggedIn user from any losses if I refresh the page ?

like image 402
Anurag Mishra Avatar asked Sep 03 '19 05:09

Anurag Mishra


3 Answers

when I refresh my page then the state value is lost

This is how React and Redux state work. They are only stored in memory while the page is loaded. It looks like you are already storing the token in local storage, which is the correct way to store data more permanently. The problem is that you never fetch the value back from local storage when your page loads. You should check if the token exists in local storage. If it does, then just fetch it. If it doesn't then redirect to the login screen.

like image 80
Code-Apprentice Avatar answered Sep 18 '22 05:09

Code-Apprentice


Two common stores of react apps are components internal state and redux. Parameters which are defined as state can not be accessed when that component is unmounted. So when you route from a page or refresh that you lose your state. But if you set a parameter in redux store you can access that parameter in whole of your app. In this case if you refresh your page you lose your redux store by routing from one page to other you still can access your store. So if you want to have a parameter in your store:

First set that in redux store and second save that in localStorage of browser. For saving and getting and removing parameters from localStorage you can refer to this link: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

But a proper way is using redux-persist library and puting your parameters in its white-list. you can read more about it here: https://github.com/rt2zz/redux-persist

I hope it would be helpful. If it is please vote me up:)

like image 45
Meisam Nazari Avatar answered Sep 20 '22 05:09

Meisam Nazari


you may have to use permanent storage, such as localstorage and hydrate the redux again with it, set the redux value as

  localstorage.setItem('user', JSON.stringify(state));

retrive it as

  const reduxState = localstorage.getItem('user');
  JSON.parse(reduxState)
like image 41
Aashish Karki Avatar answered Sep 21 '22 05:09

Aashish Karki