CorrieSparrow
CorrieSparrow

Reputation: 531

localStorage value doesn't get updated automatically

I have a simple React App. I defined several routes and one of them is Login. After user logs in successfully in Login component, I want to display his username in the top menu. I'm using localStorage to store the value and I expected that it would get updated automatically when the value changes. However, I need to refresh the page to see the change. What am I missing?

This is the code of the main App component:

import React, { Component } from 'react';
import {
BrowserRouter as Router,
      Route,
      Link,
      Redirect
    } from 'react-router-dom';

    import Login from './Login.js'
    import Register from './Register.js'
    import About from './About.js'

    class App extends Component {

      render() {
        return (
          <Router>
            <div className="topMenu">
              <Link to="/">Login</Link>
              <span> </span>
              <Link to="/register">Register</Link>
              <span> </span>
              <Link to="/about">About</Link>
              <span> </span>

              <span>Logged in user: {localStorage.getItem("username")}</span>
            </div>

            <div className="container">
              <Route exact path="/" component={Login}/>
              <Route path="/register" component={Register}/>
              <Route path="/about" component={About}/>
            </div>
          </Router>
        );
      }

    }

    export default App;

In Login component in login() method I'm simply adding username to localStorage:

 localStorage.setItem("username", username);

Shouldn't it be enough to update the displayed value in App component?

Upvotes: 1

Views: 1382

Answers (3)

PR7
PR7

Reputation: 1914

One way of doing this can be storing the name of the user in the state of app component and create a function in app component which updates the username in the state and pass that function as a callback to the login component. When the login is successfull, the login page will call this function and update the username in app component. Since the state is changed, the app component will be rendered again with new state (updated username).

import React, { Component } from 'react';
import {
BrowserRouter as Router,
  Route,
  Link,
  Redirect
} from 'react-router-dom';

import Login from './Login.js'
import Register from './Register.js'
import About from './About.js'

class App extends Component {
  state = { username: "" };

  updateUsername = () => {
    const username = localStorage.getItem("username");
    this.setState({ username: username });
  };

  render() {
    return (
      <Router>
        <div className="topMenu">
          <Link to="/">Login</Link>
          <span> </span>
          <Link to="/register">Register</Link>
          <span> </span>
          <Link to="/about">About</Link>
          <span> </span>

          <span>Logged in user: {localStorage.getItem("username")}</span>
        </div>

        <div className="container">
          <Route
            path="/login"
            render={props => <Login {...props} updateUsername={updateUsername} />}
           />
          <Route path="/register" component={Register}/>
          <Route path="/about" component={About}/>
        </div>
      </Router>
    );
  }

}

export default App;

Now the updateUsername function should be available in Login component via this.props.updateUsername. You can call this function when the login is successfull to update state in app component.

Upvotes: 2

Stefan Morcodeanu
Stefan Morcodeanu

Reputation: 2158

You can use Context API, and store all the data from local storage also in the state of application so whenever you update local storage make sure to update and state of the application and React will detect changes in the state of the app and will trigger render lifecycle.

See here documentation on how to use Context API it's very simple to implement, also working with localstorage you can use this package ngx-webstorage more inforation you can find here https://www.npmjs.com/package/ngx-webstorage

Upvotes: 2

Tomislav Milanović
Tomislav Milanović

Reputation: 495

React re-renders when the values in state or props change. You need to store the value which you get from the localStorage to the state in App component.

Since this starts to look like an app which needs to share data between many components which may not necessarily be in a parent-child relationship, using Redux may be a good idea.

Upvotes: 1

Related Questions