Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - Login Variables cached in the browser

I'm quite new to React and trying to learn it but have a strong background in backends (java/nodejs/php/...)

So first I wanted to create a login portal, basically 3 pages: - The homepage which redirects you to login if you are not authenticated - Login page - Register page

The features are working (register/login/logout) My problem is on the Homepage, if I first log in with user1, I will see Hello user1. If I log out and log in with user2, I will still see user1.

It seems that the variable is cached somehow by the browser. F5 refresh actually updates the value ... :/

This is what I've done:

In my app, I have this route:

<Provider store={store}>
      <HashRouter>
        <Switch>
          <Route path="/login" name="Login" component={Login} />
          <Route path="/register" name="Register" component={Register} />
          <PrivateRoute path="/" name="Home" component={Layout} />
        </Switch>
      </HashRouter>
    </Provider>

The provider configureStore is doing :

store.dispatch(requestUserInfo());

And this requestUserInfo() is something I created in the following class I get the token, decode it with jwt and render some user info:

import jwt_decode from 'jwt-decode'

export const REQUEST_USER = "REQUEST_USER";
export const USER_INFO = "USER_INFO";

export function requestUserInfo() {
if(localStorage.usertoken){
  const decoded = jwt_decode(localStorage.usertoken)
  let usertest = {
    "username": decoded.first_name + " " + decoded.last_name,
    "picture": "assets/img/avatars/test.png",
    "activity": 1
  } 

  return dispatch => {

      dispatch({
        type: USER_INFO,
        payload: usertest
      });

  };
} else {
  return dispatch => {
      dispatch({
        type: USER_INFO,
        payload: {"username": "","picture": "","activity": 0}
      });
  };
}
}

export default function isLogged() {
let status = false

if(localStorage.usertoken){
  try{
    if(jwt_decode(localStorage.usertoken)){
      status = true;
    }
  } catch(e){
    console.log(e)
  }

}

return status
} 

When doing the logout, I remove the token by doing : localStorage.removeItem('usertoken')

Edit: When trying to do a 1st login in a private tab, nothing is shown, the variables are empty. Looks like my variables are set after the rendering maybe?

Edit2: I put everything on github so it might be easier to debug: https://github.com/senechalm/learning-reactjs

Does anyone have any idea/suggestion on how to fix this issue/bug?

like image 399
Morgan Senechal Avatar asked Mar 19 '19 11:03

Morgan Senechal


People also ask

How data is stored in browser cache with React?

Approach: Follow these simple steps in order to store multiple cache data in ReactJS. We have created our addMultipleCacheData function which takes the user data list and store into the browser cache. When we click on the button, the function is triggered and data gets stored into the cache, and we see an alert popup.

How do I get cached data in React?

The most accessible way to fetch data with React is using the Fetch API. The Fetch API is a tool that's built into most modern browsers on the window object ( window. fetch ) and enables us to make HTTP requests very easily using JavaScript promises.

How do I clear the react JS cache?

In your developer tools. Find network tab and disable cache.


2 Answers

Looks like you have incorrect values in redux. If you are not using redux dev tools - please install it and check your values in reducer after logout and second login.

like image 54
Sasha Kos Avatar answered Oct 26 '22 22:10

Sasha Kos


I can see in the repo some issues that we can fix in 3 steps:

  1. lets redo requestUserInfo() so we return action, but not calling dispatch:
export function requestUserInfo() {
    if(sessionStorage.usertoken){
      const decoded = jwt_decode(localStorage.usertoken)
       let usertest = {
        "username": decoded.first_name + " " + decoded.last_name,
        "picture": "assets/img/avatars/sunny.png",
        "activity": 12
      } 
      return {
            type: USER_INFO,
            payload: usertest
          };        
    } else {      
      return {
            type: USER_INFO,
            payload: {username: "",picture: "",activity: 0}
          };    
    }
}
  1. in Home.js with state we map dispatch:
const mapStateToProps = (state) => state.user;

function mapDispatchToProps (dispatch) {
  return {
    requestUserInfo: ()=> dispatch(requestUserInfo()) 
  }
}
export default connect(mapStateToProps,mapDispatchToProps)(Home); 
  1. we should use componentDidMount now as componentWillMount marked UNSAFE, so remove it and add:
componentDidMount() {
    console.log("before"+this.props.username)
    this.props.requestUserInfo();
    console.log("after"+this.props.username)
}

Hope it makes sense :)

like image 24
Vladimir Avatar answered Oct 26 '22 23:10

Vladimir