Панель навигации не отображается в app.js из-за условий маршрутизации. Useeffect не срабатывает при изменении маршрута

avatar
Manoj
9 августа 2021 в 05:16
56
1
0

Здесь, в этом коде, я использую панель навигации на основе условия, если пользователь вошел в систему (если информация о пользователе хранится в локальном хранилище), за исключением компонента входа в систему, я визуализирую компонент панели навигации. Но после успешного входа в соответствующий компонент при первой маршрутизации панель навигации не отображается вверху, она отображается только в том случае, если я обновляю страницу. Я попробовал это решение, но оно мне не помогло компоненты ниже. Спасибо

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)
Источник
Drew Reese
9 августа 2021 в 05:23
0

Вы должны использовать некоторое состояние локального компонента в App для хранения состояния аутентификации и передачи состояния/обратных вызовов дочерним компонентам, отображаемым маршрутами, или использовать контекст React или избыточность для хранения глобального состояния приложения. Вы должны инициализировать состояние из localStorage и только постоянно обновлять состояние обратно в localStorage. Все ваши компоненты выполняют слишком много микроуправления localStorage. Проблема здесь в том, что App проверяет localStorage только при монтировании, поэтому перезагрузка страницы необходима для повторного считывания обновленных значений из localStorage.

Ответы (1)

avatar
Sanskar Bansal
10 августа 2021 в 06:40
0

Требуются изменения

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)