Здесь, в этом коде, я использую панель навигации на основе условия, если пользователь вошел в систему (если информация о пользователе хранится в локальном хранилище), за исключением компонента входа в систему, я визуализирую компонент панели навигации. Но после успешного входа в соответствующий компонент при первой маршрутизации панель навигации не отображается вверху, она отображается только в том случае, если я обновляю страницу. Я попробовал это решение, но оно мне не помогло компоненты ниже. Спасибо
Index.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 или избыточность для хранения глобального состояния приложения. Вы должны инициализировать состояние из localStorage и только постоянно обновлять состояние обратно в localStorage. Все ваши компоненты выполняют слишком много микроуправления localStorage. Проблема здесь в том, чтоApp
проверяет localStorage только при монтировании, поэтому перезагрузка страницы необходима для повторного считывания обновленных значений из localStorage.