Reputation: 97
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:
Upvotes: 1
Views: 3648
Reputation: 586
In React, when a component mounts
useEffect
) and update statesif 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.
Upvotes: 3
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