React Persistant Login using Zustand (State Management) — Prevent UI change on refreshing the page.

Giwon
2 min readApr 28, 2024

--

Note: Full code is at the end

After successfully retrieving the API for user login and storing the JWT tokens, the navigation bar does not change the UI for logged in users until the page is refreshed.

To solve this problem, one solution is to use a state management library to create a store and upon successful login, set the state as logged in.

npm install zustand

To create a store, setup a folder named ‘store’ and create a .ts or .js file according to what you need. In my case, I created useAuthStore.ts

You also need to install a Zustand middleware called ‘persist’ to prevent any changes when the page is constantly refreshed. As the UI may change to being user logged out.

npm i zustand-persist

Zustand is all about creating an object, it’s not very difficult and requires little boilerplate.

In my case, I’m using Typescript with React so needed to create an interface .

By setting a variable with a boolean value, set the default value to false, which indicates that the user is NOT logged in.

Create functions for a login and logout feature to call when the user logs in successfully or when the user logs out.

To persist login, you can use the stored JWT token as reference and if there is a token, you can persist login and refreshing will not change the UI to being logged out. Also, make sure the call the login() function when user login is successful as well and logout() to set a logged out state.


import { create } from 'zustand';
import { persist } from 'zustand/middleware';

interface AuthStore {
isLoggedIn: boolean;
login: () => void;
logout: () => void;
}
const useAuthStore = create(
persist<AuthStore>(
(set) => ({
isLoggedIn: false,
login: () => {
const userLocalStorage = localStorage.getItem('accessToken');
if (userLocalStorage) {
set({ isLoggedIn: true });
}
},
logout: () => {
set({ isLoggedIn: false });
localStorage.clear();
},
}),
{
name: 'userLoginStatus',
}
)
);


export default useAuthStore;

Call login() and logout() onto your functions

Lets say you have a handleLogin and handleLogout, all you have to do is call the functions into it.

const {login} = useAuthStore()

const handleLogin() => {
console.log('logged in')
login()
}
const {logout} = useAuthStore()

const handleLogOut() => {
console.log('logged out')
logout()
}

--

--