如何防止子组件重新渲染?
[英] How to prevent children component from rerendering?
本文介绍了如何防止子组件重新渲染?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我的搜索栏组件更改了布局组件的状态.因此,布局组件会触发其所有子组件的重新渲染.我试图实现 React.memo(),但它没有帮助我.请纠正我.提前致谢!
布局组件:
export default class Layout extends Component {状态 = {城市名: "",日期: "",图标: "",};searchbarSubmitHandler = e =>{const 城市名称 =e.target.children[0].firstChild.children[0].value;this.setState({城市名称:城市名称});console.log(this.state.cityName);e.preventDefault();};searchbarChangeHandler = e =>{this.setState({城市名称:e.target.value});};使成为() {返回 (<div><搜索栏提交={this.searchbarSubmitHandler}change={this.searchbarChangeHandler}/><开关><路线精确的路径=/"组件={() =><当前天气图标={this.state.icon}/>}/><路线路径="/24 小时天气"组件={每小时天气}/></开关>
);}}
搜索栏组件:
const searchbar = props =>{返回 (<div className="搜索栏"><form onSubmit={props.submit}><div className="输入"><div className="inputTextWrapper"><输入类名=输入文本"类型=文本"placeholder="城市名称..."onChange={props.change}/>
<输入类名=输入提交"类型=提交"值=搜索"/>
</表单>
);};导出默认搜索栏;
我不想重新渲染的 CurrentWeather 组件:
const currentWeather = props =>{返回 (<div className="容器"><h3>英国伦敦</h3>);};const areEqual = (prevProps, nextProps) =>prevProps === nextProps;导出默认 React.memo(currentWeather, areEqual);
解决方案
问题是
<路由精确的路径=/"组件={() =><CurrentWeather icon={this.state.icon}/>}/>
component
的工作方式是路由器使用 React.createElement 从给定的组件创建一个新的 React 元素.卸载现有组件并安装新组件,而不是仅仅更新现有组件组件"
https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Route.md#component
如果你把它改成render
,你不会得到这个效果,也不会重新创建这个组件.
<路由精确的路径=/"渲染={() =><CurrentWeather icon={this.state.icon}/>}/>
https://codesandbox.io/s/restless-hill-2ykhq显示这个工作
My searchbar component changes state of Layout component. Therefore, Layout component triggres rerendering of all its childs components. I tried to implement React.memo(), but it didn't help me. Please correct me. Thank you in advance!
Layout component:
export default class Layout extends Component {
state = {
cityName: "",
date: "",
icon: "",
};
searchbarSubmitHandler = e => {
const cityName =
e.target.children[0].firstChild.children[0].value;
this.setState({
cityName: cityName
});
console.log(this.state.cityName);
e.preventDefault();
};
searchbarChangeHandler = e => {
this.setState({
cityName: e.target.value
});
};
render() {
return (
<div>
<Searchbar
submit={this.searchbarSubmitHandler}
change={this.searchbarChangeHandler}
/>
<Switch>
<Route
exact
path="/"
component={() =>
<CurrentWeather icon={this.state.icon} />
}
/>
<Route
path="/24h-weather"
component={HourlyWeather}
/>
</Switch>
</div>
);
}
}
searchbar component:
const searchbar = props => {
return (
<div className="searchbar">
<form onSubmit={props.submit}>
<div className="inputs">
<div className="inputTextWrapper">
<input
className="inputText"
type="text"
placeholder="City name..."
onChange={props.change}
/>
</div>
<input
className="inputSubmit"
type="submit"
value="Search"
/>
</div>
</form>
</div>
);
};
export default searchbar;
CurrentWeather component which I want to not rerender:
const currentWeather = props => {
return (
<div className="container">
<h3>London, UK</h3>
<img
src={`http://openweathermap.org/img/wn/${props.icon}.png`}
alt="weather icon"
/>
</div>
);
};
const areEqual = (prevProps, nextProps) => prevProps === nextProps;
export default React.memo(currentWeather, areEqual);
解决方案
The issue is
<Route
exact
path="/"
component={() => <CurrentWeather icon={this.state.icon} />}
/>
The way that component
works is "router uses React.createElement to create a new React element from the given component. The existing component is unmounted and the new component is mounted instead of just updating the existing component"
https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Route.md#component
If you change this to render
, you will not get this effect, and it won't recreate this component.
<Route
exact
path="/"
render={() => <CurrentWeather icon={this.state.icon} />}
/>
https://codesandbox.io/s/restless-hill-2ykhq to show this working
这篇关于如何防止子组件重新渲染?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!