reactjs - 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>
);
}
}
解决方案
当父视图重新渲染时,所有可见的子视图也会重新渲染。如果它是一个功能组件,你可以将你的 home 组件包装在一个React.memo中,或者如果它是一个类,你可以使用shouldComponentUpdate生命周期方法。这应该可以防止不必要的重新渲染。
推荐阅读
- reactjs - Apollo 客户端返回值的类型
- json - 当数据(json)在数据帧中不是所需格式时处理异常
- ios - ios app 在 ipad 上运行,launchscreen.storyboard 旋转屏幕问题
- chef-infra - 使用 Chef 安装和启用 python 3
- vba - 自动删除电子邮件正文中警告周围的边框
- c++ - 为什么这个 if(s[j]==s[i] && i>0) 条件不适用于这个 [{()}]
- fluentd - JSON 和非 JSON 结束日志的 Fluentd 解析错误
- javascript - React - 如何从子组件获取状态数据?
- excel - 添加或删除不相关的工作表时 Excel VBA UDF 返回 #VALUE 错误
- angularjs - 无法在 .net core mvc 中加载 angularJS 视图