//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
在useEffect一旦我从localStorage获得用户,我有setUser与localStorage信息,也在下一行,我有setIsLoggedIn(true)。是否禁止在同一个函数或同一个useEffect内设置两个状态?我不能理解,组件正在渲染自己的循环。setUser和setIsLoggedIn作为true的最好方法是什么?如果我注释setIsLoggedIn(true)行,那么问题就解决了。每次我setIsLoggedIn(真实的)是导致多个渲染,我不知道为什么这条线是导致问题
不知道这里有什么问题,但设置两个状态应该不是问题。
useEffect(() => {
const storedUser = localStorage.getItem('chatUserInfo')
if (storedUser) {
setIsLoggedIn(true)
setUser(JSON.parse(localStorage.getItem('chatUserInfo') || ''))
} else {
router.push('/')
}
}, []);
这里是一个工作演示https://stackblitz.com/edit/react-ts-1draoe?embed=1&file=App.tsx