如何在App.js中使用React Hooks根据localStorage值切换元素类名
解决方案
你完全不需要用原生DOM操作修改类名,用React自带的动态类名绑定就能实现需求,还能避免DOM未挂载找不到元素的报错,优化后代码如下:
import React, { useEffect, useState } from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import Login from './components/Login/Login'; import Navbar from './components/Navbar/Navbar'; import Homepage from './components/Homepage/Homepage'; import Contentpage from './components/Contentpage/Contentpage'; import TerminalUI from './components/Terminal/Terminal'; import './App.css'; function App() { // 初始化状态时直接读取本地存储判断登录状态,避免不必要的二次渲染 const [status, setStatus] = useState(!!window.localStorage.getItem('user')); useEffect(() => { // 可选:监听storage事件,兼容多标签页登录/登出状态同步 const handleStorageChange = (e) => { if (e.key === 'user') { setStatus(!!e.newValue); } }; window.addEventListener('storage', handleStorageChange); return () => window.removeEventListener('storage', handleStorageChange); }, []); // 登录/登出完成后调用该方法同步状态 const updateLoginStatus = (isLogin) => { setStatus(isLogin); if (!isLogin) { window.localStorage.removeItem('user'); } }; return ( <React.Fragment> <Router> {/* 登出按钮一般在导航栏,传入更新方法,登出完成后调用updateLoginStatus(false) */} <Navbar updateLoginStatus={updateLoginStatus} /> {/* 动态绑定类名,登录状态为true自动加main类,false自动移除 */} <div id="mainDiv" className={status ? 'main' : ''}> <Switch> <Route exact path="/" component={Homepage} /> {/* 登录组件传入更新方法,登录成功后调用updateLoginStatus(true) */} <Route path="/login" render={(props) => <Login {...props} updateLoginStatus={updateLoginStatus} />} /> <Route path="/chapters" component={Contentpage} /> <Route path="/terminal" component={TerminalUI} /> </Switch> </div> </Router> </React.Fragment> ); } export default App;
原代码问题说明
- 直接操作DOM不符合React声明式编程逻辑,还可能出现DOM未挂载时
getElementById返回null引发的报错 - 直接读取
window.localStorage.user不是响应式数据,登录/登出修改本地存储后,状态不会自动同步更新 - useEffect依赖设置不合理,初始化时设置状态会触发重复执行,逻辑冗余
内容的提问来源于stack exchange,提问作者knight11
相关产品推荐
相关产品推荐

