localStorage存在值但React AuthContext中user为null引发报错
问题原因
你的代码崩溃是因为组件首次渲染时,AuthContext里的user还是初始值null,这时候直接访问user.username就会抛出"Cannot read properties of null"的错误。虽然之后useEffect会从localStorage加载用户信息并更新state,但首次渲染的瞬间错误已经触发了。
解决方案
有三种简单的修复方式,选一种就行:
1. 使用可选链操作符(推荐)
直接在访问username前加?.,当user为null/undefined时会直接返回undefined,不会报错:
const Home = () => { const { user } = useAuthContext() return ( <div> <Container> <Routes> <Route path="/" element={user?.username === "admin" ? <Dashboard title="Dashboard" user="User" /> : <Navigate to="/login" />} /> </Routes> </Container> </div> ) }
2. 先判断user是否存在
在访问user.username之前,先确认user不是null:
const Home = () => { const { user } = useAuthContext() return ( <div> <Container> <Routes> <Route path="/" element={user && user.username === "admin" ? <Dashboard title="Dashboard" user="User" /> : <Navigate to="/login" />} /> </Routes> </Container> </div> ) }
3. 添加加载状态(更严谨)
如果想在用户信息加载完成前显示加载提示,可以给AuthContext加上loading状态:
首先修改AuthContextProvider:
export const authReducer = (state, action) => { switch (action.type) { case 'LOGIN': return { user: action.payload, isLoading: false } case 'LOGOUT': return { user: null, isLoading: false } case 'SET_LOADING': return { ...state, isLoading: action.payload } default: return state } } export const AuthContextProvider = ({ children }) => { const [state, dispatch] = useReducer(authReducer, { user: null, isLoading: true // 新增初始加载状态 }) useEffect(() => { const user = JSON.parse(localStorage.getItem('user')) if(user){ dispatch({type: 'LOGIN', payload: user}) } else { dispatch({type: 'SET_LOADING', payload: false}) } },[]) return ( <AuthContext.Provider value={{ ...state, dispatch }}> {children} </AuthContext.Provider> ) }
然后在Home组件里先判断加载状态:
const Home = () => { const { user, isLoading } = useAuthContext() if(isLoading){ return <div>加载中...</div> } return ( <div> <Container> <Routes> <Route path="/" element={user?.username === "admin" ? <Dashboard title="Dashboard" user="User" /> : <Navigate to="/login" />} /> </Routes> </Container> </div> ) }
内容的提问来源于stack exchange,提问作者kevthedevv
相关产品推荐
相关产品推荐

