【发布时间】:2018-08-18 18:40:04
【问题描述】:
我有一个父组件,它是一个包含标题HeaderComponent 的平面列表。这个HeaderComponent 是我创建的一个自定义组件,它包含它自己的 2 个子组件。每当我刷新列表时,我都会将一个布尔值传递给HeaderComponent,作为传递给它自己的孩子的道具,我这样做是为了检查每个组件是否需要获取新数据。问题是每当父级刷新并设置一个新状态时,子组件的构造函数每次都会被调用。不应该只在父级初始化时调用构造函数,然后所有进一步的调用都涉及调用子级的 shouldComponentUpdate 方法以查看它是否需要更新。
父组件
_renderHeader = () => {
return <HeaderComponent Items={this.state.Data} refresh={this.state.refresh}/>;
};
render() {
console.log("TAG_RENDER render called " + this.state.refresh);
return (
<FlatList
refreshing={this.state.refresh}
onRefresh={() => {
console.log("onRefresh");
this.setState({
refresh: true
}, () => {
this._fetchData();
});
}}
......
ListHeaderComponent={() => this._renderHeader()}
.......
/>
);
}
标题组件
export default class HeaderComponent extends React.Component {
constructor(props) {
super(props);
console.debug("HeaderComponent");
}
render() {
return (
<MainHeader Items={this.props.Items}/>
<SubHeader refresh={this.props.refresh}/>
);
}
}
每当父组件刷新时,MainHeader 和 Subheader 的构造函数就会被调用。这是否意味着它每次刷新时都会创建新的子组件,因为我可以看到子组件的渲染也被多次调用。
【问题讨论】:
-
constructor的HeaderComponent怎么样?它是否也被多次调用? -
确实如此,我还注意到用
ListHeaderComponent={this._renderHeader()}替换ListHeaderComponent={() => this._renderHeader()}可以防止这种情况发生并给我正在寻找的行为,这是否意味着匿名函数正在创建 @ 的新实例987654332@ 每次都是这样,这就是为什么 react 将其检测为新组件而从不检查现有组件的原因? -
React 指南说,使用匿名函数可能会产生副作用,即即使子组件没有更改,子组件也会呈现不必要的内容。
-
@G_S 所以用实例函数替换我所有的匿名函数是一个好主意,就像声明函数并使用它们的默认方式一样,不仅用于此,还用于网络调用和设置状态来电?
-
是的。根据反应文档,需要使用 bind() 或类属性语法。
标签: javascript reactjs react-native ecmascript-6 react-props