多次调用子组件构造函数

时间:2018-03-10 07:30:14

标签: javascript reactjs react-native ecmascript-6 react-props

我有一个父组件,它是一个包含标题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}/>
        );
    }

}  

只要父组件刷新,就会调用MainHeaderSubheader的构造函数。这是否意味着每次刷新时都会创建新的子组件,因为我可以看到子项的渲染也被多次调用。

3 个答案:

答案 0 :(得分:8)

控制您的index.js文件。如果看到<React.StrictMode>,则应更改为<>。这解决了我的问题。

应为:

ReactDOM.render(
  <>
    <App/>
  </>,
  document.getElementById('root')
);

答案 1 :(得分:6)

如答案之一所述,删除严格模式可以解决此问题。之所以这么做,是因为严格模式故意两次调用“渲染”方法以检测潜在问题。

反应分为两个阶段:渲染和提交。渲染阶段检查并确定要应用的新更改。并在提交阶段应用它。

渲染阶段生命周期包括以下方法:构造函数,UNSAFE_componentWillMount,UNSAFE_componentWillReceiveProps,...,render等。

渲染阶段很耗时,并且通常被分成几部分以释放浏览器。渲染阶段可能在提交阶段之前多次调用(通常非常快)。 由于渲染阶段方法不止一次被调用,因此重要的是,这些方法都不应该有任何问题或副作用。

因此,为了突出显示可能的副作用以使其易于发现,显式地进行了响应,两次调用了render阶段方法。

您可以在:https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects:)

上了解更多相关信息。

答案 2 :(得分:2)

严格模式无法自动为您检测副作用,但可以通过使其更具确定性来帮助您发现它们。这是通过有意重复调用以下功能来完成的:

  • 类组件的构造函数,呈现器和shouldComponentUpdate 方法
  • 类组件的静态getDerivedStateFromProps方法
  • 功能组件主体
  • 状态更新程序功能(setState的第一个参数)
  • 传递给useState,useMemo或useReducer的函数

https://reactjs.org/docs/strict-mode.html

如网站所述, 注意: 这仅适用于开发模式。在生产模式下不会重复调用生命周期。