//ChatProvider.tsx
import { useRouter } from 'next/router'
import React, { createContext, ReactNode, useEffect, useState } from 'react'
export interface IUser {
name: string
email: string
token: string
pic: string
}
export interface userContextInterface {
user: IUser | null
isLoggedIn: boolean
login: (_: IUser) => void
logOut: () => void
}
const intialContext: userContextInterface = {
user: null,
isLoggedIn: false,
login: (_: IUser) => null,
logOut: () => null,
}
export const ChatContext = createContext<userContextInterface>(intialContext)
const ChatProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [user, setUser] = useState<IUser | null>(null)
const [isLoggedIn, setIsLoggedIn] = useState(false)
const router = useRouter()
const loginUser = (userInfo: IUser) => {
setUser(userInfo)
setIsLoggedIn(true)
localStorage.setItem('chatUserInfo', JSON.stringify(userInfo))
}
const logOut = () => {
setIsLoggedIn(false)
localStorage.removeItem('chatUserInfo')
setUser(null)
}
//this is getting printed in a loop like 100 times
console.log('hey context api is running')
useEffect(() => {
console.log('use effect is running')
const storedUser = localStorage.getItem('chatUserInfo')
console.log('is there user', storedUser)
let userInfo: IUser | null = null
if (storedUser) {
userInfo = JSON.parse(localStorage.getItem('chatUserInfo') || '')
setUser(userInfo)
//commenting setIsLoggedIn below line fixes the issue
setIsLoggedIn(true)
} else {
router.push('/')
}
}, [])
return (
<ChatContext.Provider
value={{
user,
isLoggedIn,
login: loginUser,
logOut: logOut,
}}
>
{children}
</ChatContext.Provider>
)
}
export default ChatProvider
In the useEffect once I get user from localStorage I have setUser with localstorage info, also on the next line, I have setIsLoggedIn(true). Is setting two states in the same function or inside same useEffect prohibited? I am not able to understand, the component is rendering itself in a loop. What's the best way to setUser and also setIsLoggedIn as true? If I comment the line setIsLoggedIn(true) then the issue is resolved. Everytime I setIsLoggedIn(true) it's causing multiple renders, I don't know why this line is causing problem
Not sure whats wrong here, but setting two states shouldn't be a problem.
useEffect(() => {
const storedUser = localStorage.getItem('chatUserInfo')
if (storedUser) {
setIsLoggedIn(true)
setUser(JSON.parse(localStorage.getItem('chatUserInfo') || ''))
} else {
router.push('/')
}
}, []);
here is a working demo https://stackblitz.com/edit/react-ts-1draoe?embed=1&file=App.tsx