导航栏不会根据路由条件在 app.js 中呈现。路由更改时不会触发 Useeffect
Posted
技术标签:
【中文标题】导航栏不会根据路由条件在 app.js 中呈现。路由更改时不会触发 Useeffect【英文标题】:Navbar is not rendering in app.js based on routing condition. Useeffect is not getting triggered on route change 【发布时间】:2021-10-12 20:33:01 【问题描述】:在此代码中,如果用户已登录(如果用户信息存储在本地存储中),我将根据条件使用导航栏,除了登录组件,我正在渲染导航栏组件。 但是在各自的组件中成功登录后,在第一次路由时,它没有在顶部显示导航栏,只有在我刷新页面时才会显示。 I tried this solution, But this solution didnt work for me 组件如下。 谢谢你
索引.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import 'bootstrap/dist/css/bootstrap.min.css';
import BrowserRouter from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<BrowserRouter><App /></BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
App.js
import React, useEffect,useState from 'react'
import BrowserRouter as Router, Switch, Route,withRouter from 'react-router-dom'
import Login from './components/login/Login'
import Admin from './components/admin/Admin'
import ProtectedRoute from './ProtectedRoute'
import Navbar from './components/Navbar/Navbar'
const App = () =>
const [nb, setNb] = useState(false)
const checkIsAuth = () =>
const _isAuth = localStorage.getItem('isAuth');
const _user = localStorage.getItem('user');
const _password = localStorage.getItem('password');
if (_isAuth && _user && _password) setNb(true)
useEffect(() =>
checkIsAuth()
, [])
return (
<div style= textAlign: "center" >
nb && <Navbar />
<Switch>
<ProtectedRoute exact path=`/admin` component=Admin />
<Route exact path="/" component=Login />
</Switch>
</div>
);
export default withRouter(App);
登录.js
import React, useEffect, useState from 'react'
import useHistory from 'react-router-dom'
import Form, Button from 'react-bootstrap'
import withRouter from 'react-router-dom'
const Login = () =>
const history = useHistory()
const [userName, setUserName] = useState('')
const [password, setPassword] = useState('')
const submit = () =>
if ((userName === 'admin' || userName === 'operator' || userName === 'supervisor') && password === 'welcome')
localStorage.setItem('user', userName)
localStorage.setItem('isAuth', true)
localStorage.setItem('password', password)
setPassword('');
setUserName('');
history.push(`/$userName`)
else if (!((userName === 'admin' || userName === 'operator' || userName === 'supervisor') && password === 'welcome'))
alert("Invalid Credentials")
setPassword('')
setUserName('')
history.push(`/`)
const checkIsAuth = () =>
const _isAuth = localStorage.getItem('isAuth');
const _user = localStorage.getItem('user');
const _password = localStorage.getItem('password');
if (_isAuth && _user && _password) history.push(`/$localStorage.getItem('user')`)
useEffect(() =>
checkIsAuth()
, [])
return (
<div>
<Form>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Username</Form.Label>
<Form.Control type="text" placeholder="Enter Username" onChange=e => setUserName(e.target.value)
/>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" onChange=e => setPassword(e.target.value) />
</Form.Group>
<Button variant="primary" onClick=submit>
Submit
</Button>
</Form>
</div>
)
export default withRouter(Login)
ProtectedRoute.js
import React from 'react'
import Route, Redirect from 'react-router-dom'
const ProtectedRoute = ( component: Component, ...rest ) =>
const checkIsAuth = () =>
const _isAuth = localStorage.getItem('isAuth');
const _user = localStorage.getItem('user');
const _password = localStorage.getItem('password');
let res = isAuth: !!_isAuth, user: _user, password: _password
return res
return (
<Route ...rest
render=(props) =>
if (checkIsAuth().isAuth && checkIsAuth().user && checkIsAuth().password)
return <Component />
else
return <Redirect to= pathname: '/', state: from: props.location />
/>
)
export default ProtectedRoute
Admin.js
import React from 'react'
import withRouter from 'react-router-dom'
const Admin = () =>
return (
<div>
Admin
</div>
)
export default withRouter(Admin)
【问题讨论】:
您应该在App
中使用一些本地组件状态来保存身份验证状态并将状态/回调传递给路由呈现的子组件,或者使用 React 上下文或 redux 来保存全局应用程序状态。您应该从 localStorage 初始化状态,并且只将状态更新持久化回 localStorage。你的组件都在做太多的 localStorage 微管理。这里的问题是 App
仅在安装时检查 localStorage,这就是为什么需要重新加载页面才能从 localStorage 重新读取更新的值。
【参考方案1】:
需要更改
App.js
import React, useEffect,useState from 'react'
import BrowserRouter as Router, Switch, Route,withRouter from 'react-router-dom'
import Login from './components/login/Login'
import Admin from './components/admin/Admin'
import ProtectedRoute from './ProtectedRoute'
import Navbar from './components/Navbar/Navbar'
const App = () =>
const [nb, setNb] = useState(false)
const checkIsAuth = () =>
const _isAuth = localStorage.getItem('isAuth');
const _user = localStorage.getItem('user');
const _password = localStorage.getItem('password');
if (_isAuth && _user && _password) setNb(true)
useEffect(() =>
checkIsAuth()
, [])
return (
<div style= textAlign: "center" >
nb && <Navbar />
<Switch>
<ProtectedRoute exact path=`/admin` component=Admin />
<Route exact path="/" render=(routerProps) => <Login setNb=setNb/> />
</Switch>
</div>
);
export default withRouter(App);
登录.js
import React, useEffect, useState from 'react'
import useHistory from 'react-router-dom'
import Form, Button from 'react-bootstrap'
import withRouter from 'react-router-dom'
const Login = (setNb) =>
const history = useHistory()
const [userName, setUserName] = useState('')
const [password, setPassword] = useState('')
const submit = () =>
if ((userName === 'admin' || userName === 'operator' || userName === 'supervisor') && password === 'welcome')
localStorage.setItem('user', userName)
localStorage.setItem('isAuth', true)
localStorage.setItem('password', password)
setPassword('');
setUserName('');
history.push(`/$userName`);
setNb(true);
else if (!((userName === 'admin' || userName === 'operator' || userName === 'supervisor') && password === 'welcome'))
alert("Invalid Credentials")
setPassword('')
setUserName('')
history.push(`/`)
const checkIsAuth = () =>
const _isAuth = localStorage.getItem('isAuth');
const _user = localStorage.getItem('user');
const _password = localStorage.getItem('password');
if (_isAuth && _user && _password) history.push(`/$localStorage.getItem('user')`)
useEffect(() =>
checkIsAuth()
, [])
return (
<div>
<Form>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Username</Form.Label>
<Form.Control type="text" placeholder="Enter Username" onChange=e => setUserName(e.target.value)
/>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" onChange=e => setPassword(e.target.value) />
</Form.Group>
<Button variant="primary" onClick=submit>
Submit
</Button>
</Form>
</div>
)
export default withRouter(Login)
【讨论】:
以上是关于导航栏不会根据路由条件在 app.js 中呈现。路由更改时不会触发 Useeffect的主要内容,如果未能解决你的问题,请参考以下文章
React&Material UI-如何根据路线删除导航按钮/链接?