Mani Malhotra
Mani Malhotra

Reputation: 97

Local Storage values not getting loaded in React App

I am new to React and following one of the video series available on Udemy (React for the rest of us by Brad Schiff). The author has provided a backend system for user login etc. When the user logs in, the backend server sends 3 values in response to a successful login: the login token, the user name and the avatar url (a dummy image from gravatar.com). These values are then stored in local storage from where they can be displayed on the UI:

    const response = await axios.post("http://localhost:8080/login", {username, password});

    if (response.data) {
        // if response contains token, set login flag to true
        props.loginFlagHandler(true);

        // save user token, username, avatar in localstorage
        localStorage.setItem("username", response.data.username);
        localStorage.setItem("loginToken", response.data.token);
        localStorage.setItem("avatar", response.data.avatar); }

Now, when I log in and the UI updates, the values received from server are successfully stored in local storage of my browser, but they are not getting reflected on the UI. The avatar image doesn't load and the Welcome message that should display the username doesn't work as expected (see the 1st image below). The Welcome message should read "Hello <username>, your feed is empty"

However, once I hit refresh, both the Avatar Image and the User name get displayed as they should, on their relevant place. (refer 2nd image).

In both the cases, I am referring to the localStorage variable as below:

<img className="small-header-avatar" src={localStorage.getItem("avatar")} />

And:

<h2 className="text-center">
  Hello <strong>{localStorage.getItem("username")}</strong>, your feed is empty.
</h2>

I think this should be a noob thing that I'm missing here. Nevertheless, thanks in advance:

Empty user name on welcome message and avatar image

enter image description here

Upvotes: 1

Views: 3648

Answers (2)

miraj
miraj

Reputation: 586

In React, when a component mounts

  1. states are load
  2. UI prints with the initial states
  3. Lifecycle hooks run (e.g. useEffect) and update states
  4. DOM re-prints with updated states

if you don't use state in your component then you should follow the above workflow to update your UI. Though I don't know what your props.loginFlagHandler(true) does, I am giving an example below.

const [isDataStored, setIsDataStored] = useState(false)

useEffect(() => {
  const fetchData = async () => {
    const response = await axios.post("http://localhost:8080/login", {username, password});

    if (response.data) {
      // if response contains token, set login flag to true
      props.loginFlagHandler(true);

      // save user token, username, avatar in localstorage
      localStorage.setItem("username", response.data.username);
      localStorage.setItem("loginToken", response.data.token);
      localStorage.setItem("avatar", response.data.avatar);
    }
    setIsDataStored(true)
  }
}, [])

you can also try lazy loading your child component. enter image description here

Upvotes: 3

BTSM
BTSM

Reputation: 1663

Well you should use state like this.

const [avatar, setAvatar] = useState("");
const [username, setUsername] = useState("");

useEffect(() => {  
      setUsername(localStorage.getItem("username"))
      setAvatar(localStorage.getItem("avatar"))
    
  
})

................
<img className="small-header-avatar" src={avatar} />
And:

<h2 className="text-center">
  Hello <strong>{username}</strong>, your feed is empty.
</h2>

Upvotes: 1

Related Questions