首页 > 解决方案 > React 路由组件在父组件状态改变时重新渲染

问题描述

在 App.js 中,我将状态和函数作为道具传递给 Header.js、SideDrawer.js、Footer.js。每次 App.js 的状态发生变化时(即当我单击 Header.js 上的链接时),Home.js 都会重新渲染(我没有向 Home.js 传递任何内容),这正常吗?如何防止 Home.js 重新渲染?

我已经尝试将 Home Component(它是一个类组件)更改为 PureComponent,但是当 App 的状态发生变化时它仍然会重新渲染。

应用程序.js

class App extends React.Component {
  state = {
    sideDrawerOpen: false,
    subMenuOpen: false,
    modalOpen: false
  };

  componentDidMount() {
    store.dispatch(loadUser());
  }

  sideDrawerOpenHandler = () => {
    this.setState(prevState => {
      return { sideDrawerOpen: !prevState.sideDrawerOpen };
    });
  };

  sideDrawerCloseHandler = () => {
    this.setState({
      sideDrawerOpen: false
    });
  };

  subMenuOpenHandler = () => {
    this.setState(
      prevState => {
        return { subMenuOpen: !prevState.subMenuOpen };
      },
      () => {
        document.addEventListener("click", this.subMenuCloseHandler);
      }
    );
  };

  subMenuCloseHandler = () => {
    this.setState(
      {
        subMenuOpen: false
      },
      () => {
        document.removeEventListener("click", this.subMenuCloseHandler);
      }
    );
  };

  modalOpenHandler = () => {
    this.setState(prevState => {
      return { modalOpen: !prevState.modalOpen };
    });
  };
  modalCloseHandler = () => {
    this.setState({
      modalOpen: false
    });
  };

  render() {
    let backDrop;

    if (this.state.sideDrawerOpen || this.state.modalOpen) {
      backDrop = (
        <Backdrop
          sideDrawerCloseHandler={this.sideDrawerCloseHandler}
          subMenuCloseHandler={this.subMenuCloseHandler}
          modalCloseHandler={this.modalCloseHandler}
        />
      );
    }

    return (
      <Provider store={store}>
        <AlertProvider template={AlertTemplate} {...alertOptions}>
          <Router>
            <Header
              sideDrawerOpenHandler={this.sideDrawerOpenHandler}
              subMenuOpenHandler={this.subMenuOpenHandler}
              subMenuOpen={this.state.subMenuOpen}
              // subMenuCloseHandler={this.subMenuCloseHandler}
            />
            <Alerts />
            {this.state.modalOpen && (
              <Trivia modalCloseHandler={this.modalCloseHandler} />
            )}
            <SideDrawer
              sideDrawerOpen={this.state.sideDrawerOpen}
              sideDrawerCloseHandler={this.sideDrawerCloseHandler}
              subMenuOpenHandler={this.subMenuOpenHandler}
              subMenuOpen={this.state.subMenuOpen}
              subMenuCloseHandler={this.subMenuCloseHandler}
            />
            {backDrop}
            <Footer
              modalOpenHandler={this.modalOpenHandler}
              subMenuCloseHandler={this.subMenuCloseHandler}
            />
            <main>
              <Switch>
                <Route exact path="/" component={Home} />
                <Route path="/roster/lakers" component={Lakers} />
                <Route path="/roster/celtics" component={Celtics} />
                <Route path="/roster/rockets" component={Rockets} />
                <Route path="/roster/raptors" component={Raptors} />
                <Route path="/roster/clippers" component={Clippers} />
                <Route path="/roster/bucks" component={Bucks} />
                <Route path="/login" component={Login} />
                <Route path="/register" component={Register} />
              </Switch>
            </main>
          </Router>
        </AlertProvider>
      </Provider>
    );
  }
}

标签: reactjsreact-router

解决方案


当父视图重新渲染时,所有可见的子视图也会重新渲染。如果它是一个功能组件,你可以将你的 home 组件包装在一个React.memo中,或者如果它是一个类,你可以使用shouldComponentUpdate生命周期方法。这应该可以防止不必要的重新渲染。


推荐阅读