基于全局状态布尔值切换导航栏出现白屏问题求助
React Context 实现全局状态导致页面白屏问题排查与修复
我正在使用React Context API实现全局状态,希望根据用户登录状态切换导航栏,但页面出现白屏,以下是相关代码及问题修复方案:
AppContext.js
import React from "react"; // ./components/AppContext.js const AppContext = React.createContext(); export default AppContext;
Index.js
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import reportWebVitals from './reportWebVitals'; import { CookiesProvider } from 'react-cookie'; import App from "./App"; import AppContext from "./components/AppContext"; // index.js const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <CookiesProvider> <App/> </CookiesProvider> </React.StrictMode> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: reportWebVitals();
App.js(存在问题版本)
import React, {useState} from 'react'; import './App.css'; import Home from './Home'; import {BrowserRouter as Router, Route, Routes} from 'react-router-dom'; import User from "./User"; import NavBarSI from "./components/NavBarSignedIn"; import NavBarGL from "./components/NavBarGeneral"; import AppContext from "./components/AppContext"; //App.js const App = () => { const userSettings = { setting2name: setting2value, setSetting2value }; const [setting2value, setSetting2value] = useState(false); const navbar = setting2value ? <NavBarSI/> : <NavBarGL/> return ( <Router> <AppContext.Provider value={userSettings}> {navbar} <NavBarSI/> <div> <Routes> <Route exact path="/" element={<Home/>}/> <Route exact path="/user" element={<User/>}/> </Routes> </div> </AppContext.Provider> </Router> ); } export default App;
Home.js
import React, {useContext, useEffect, useState} from 'react'; import './App.css'; import { Button, Container } from 'reactstrap'; import { useCookies } from 'react-cookie'; import AppContext from "./components/AppContext"; // Home.js const Home = () => { const myContext = useContext(AppContext); const [authenticated, setAuthenticated] = useState("authenticated"); const [loading, setLoading] = useState(false); const [user, setUser] = useState(undefined); const [cookies] = useCookies(['XSRF-TOKEN']); useEffect(() => { setLoading(true); fetch('/user', { credentials: 'include' }) .then(response => response.text()) .then(body => { if (body === '') { setAuthenticated(false); } else { setUser(JSON.parse(body)); setAuthenticated(true); myContext.setSetting2value(true); } setLoading(false); }); }, [setAuthenticated, setLoading, setUser]) const login = () => { let port = (window.location.port ? ':' + window.location.port : ''); if (port === ':3000') { port = ':8080'; } window.location.href = `//${window.location.hostname}${port}/private`; } const logout = () => { fetch('/user/logout', { method: 'POST', credentials: 'include', headers: { 'X-XSRF-TOKEN': cookies['XSRF-TOKEN'] } }) .then(res => res.json()) .then(response => { window.location.href = `${response.logoutUrl}&returnTo=${window.location.origin}`; }); } const message = user ? <h2>Welcome, {user.name}!</h2> : <p>Please log in to manage your JUG Tour.</p>; const button = authenticated ? <div> <br/> <Button color="link" onClick={logout}>Logout</Button> </div> : <Button color="primary" onClick={login}>Login</Button>;; if (loading) { return <p>Loading...</p>; } return ( <div> <Container fluid> {message} {button} </Container> </div> ); } export default Home;
问题分析与修复
1. 变量声明顺序错误(白屏直接原因)
在App.js中,userSettings对象的定义在useState声明之前,导致setting2value和setSetting2value未被声明就被引用,触发ReferenceError,直接导致页面白屏。
修复方法:调整声明顺序,先定义useState再创建context值对象:
const App = () => { // 先声明state const [setting2value, setSetting2value] = useState(false); // 再创建context值 const userSettings = { setting2name: setting2value, setSetting2value }; const navbar = setting2value ? <NavBarSI/> : <NavBarGL/> return ( <Router> <AppContext.Provider value={userSettings}> {navbar} {/* 移除重复渲染的<NavBarSI/> */} <div> <Routes> <Route exact path="/" element={<Home/>}/> <Route exact path="/user" element={<User/>}/> </Routes> </div> </AppContext.Provider> </Router> ); }
2. 导航栏重复渲染
原App.js中同时渲染了{navbar}和<NavBarSI/>,会导致页面出现两个导航栏,需移除重复的<NavBarSI/>。
3. Home.js中的潜在问题
authenticated初始值为字符串"authenticated",应改为布尔值false,避免初始状态判断逻辑错误:const [authenticated, setAuthenticated] = useState(false);- useEffect依赖数组缺少
myContext.setSetting2value,会触发React警告,需补充:useEffect(() => { // ...原有逻辑 }, [setAuthenticated, setLoading, setUser, myContext.setSetting2value])
修复后验证
完成上述修改后,页面将正常渲染,登录状态变更时会自动切换导航栏组件,同时消除控制台错误与警告。
内容的提问来源于stack exchange,提问作者Meadas
相关产品推荐
相关产品推荐

