react.js 如何在触发某些操作时重新渲染 App.js

IT技术 javascript reactjs
2021-05-16 15:48:55

我创建了一个带有标题和简单授权的简单 react.js,因此如果用户已登录(用户对象设置在 localstorage 中) - 导航栏显示,如果没有 - 导航栏隐藏。代码如下:

#App.js
import React from 'react';
import { connect } from 'react-redux';
import LoginPage from "./components/loginPage/loginPage";
import MainPage from "./components/dashboard/mainPage";
import AuditPage from "./components/auditPage/AuditPage.js";
import Navbar from "./components/navbar/Navbar";
import Test01 from "./components/dev/test01";
import Test02 from "./components/dev/test02";
import {Router, Route, BrowserRouter, Redirect, Switch} from 'react-router-dom';
import {history} from "./helpers/history";
import TestsNav from "./components/dev/TestsNav";


class App extends React.Component   {
  constructor(props){
    super(props);
  }
  render() {

    return (
        <div className="main-container">
            <Router history={history}>
                {localStorage.getItem('user') && (//this fires only once, when the page is loaded
                    <Navbar history={history} />
                )}

                <Switch>
                    <Route exact path="/login" component={LoginPage}/>
                    <Route exact path="/" component={MainPage}/>
                    <Route exact path="/audit" component={AuditPage}/>
                    <Route exact path="/test01" component={Test01}/>
                    <Route exact path="/test02" component={Test02}/>
                </Switch>
            </Router>
        </div>
    )
  }
}

function mapStateToProps(state) {
  return {
   };
}

const connectedApp = connect(mapStateToProps)(App);
export default connectedApp;

问题在于,当用户登录并将数据设置为 localstorage 时 - 导航栏不显示 - 类 App.js 不会重新呈现。我得到了导航栏的渲染条件 - 但它只在页面加载时触发一次。所以如果我想显示导航栏,我需要按 f5,然后它才会出现。任何解决方法的想法都会受到欢迎。谢谢你。

3个回答

这是我为这种情况所做的。

我的路线部分:

<Router>
    <Switch>
    {privateRoutes.map(({ path, component: Component }, idx) => (
        <PrivateRoute
        key={idx}
        exact
        path={path}
        component={() => (
            <SideNav>
              <Component />
            </SideNav>
        )}
        />
    ))}

    <IsAuthenticated exact path="/login" component={LoginPage} />
    </Switch>
</Router>

IsAuthenticated 组件:

import React from "react";
import { Redirect, Route } from "react-router-dom";
import { useSelector } from "react-redux";


function IsAuthenticated({ component: Component, ...props }) {
  const isAuthenticated = useSelector(state => state.User.isLogin)
  return (
    <Route
      {...props}
      render={props =>
        !isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}

export default IsAuthenticated;

私有路由组件:

import React from "react";
import { Redirect, Route } from "react-router-dom";
import { useSelector } from "react-redux";

function PrivateRoute({ component: Component, ...props }) {
  const isAuthenticated = useSelector(state => state.User.isLogin);
  return (
    <Route
      render={props =>
        isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
      {...props}
    />
  );
}

export default PrivateRoute;

我的路由文件包含如下内容:

export const privateRoutes = [
  {
    path: "/",
    component: HomePage
  },
];

我使用 redux 来检查用户是否经过身份验证,并在应用程序启动时在 App.js 中进行检查。

将此组件中的函数传递到登录页面。登录后调用该函数(这将设置一个状态并重新渲染组件)。

class App extends React.Component   {
  constructor(props){
    super(props);
    this,state = {
      isAuthenticated: false
    }
  }

  setIsAuthenticated = (isAuthenticated) => this.setState({ isAuthenticated });
  render() {

    return (
        <div className="main-container">
            <Router history={history}>
                {(this.state.isAuthenticated || localStorage.getItem('user')) && (//this fires only once, when the page is loaded
                    <Navbar history={history} />
                )}

                <Switch>
                    <Route exact path="/login" render={() => <LoginPage setIsAuthenticated={this.setIsAuthenticated} />}/>
// call props.setIsAuthenticated from login page after loginng in.
                    <Route exact path="/" component={MainPage}/>
                    <Route exact path="/audit" component={AuditPage}/>
                    <Route exact path="/test01" component={Test01}/>
                    <Route exact path="/test02" component={Test02}/>
                </Switch>
            </Router>
        </div>
    )
  }
}

function mapStateToProps(state) {
  return {
   };
}

const connectedApp = connect(mapStateToProps)(App);
export default connectedApp;

这太容易了。在 App.js 中,调用一个函数,该函数表示,return App;