ComponentWillMount仅在第一次触发?

时间:2018-04-17 15:11:22

标签: react-native components lifecycle native-base

MainComponent:

<Tabs 
  initialPage={this.props.day}
  tabBarUnderlineStyle={{ backgroundColor: '#5AF158' }} 
  renderTabBar={() => <ScrollableTab />}>
  {this.renderTabHeader()}
</Tabs>

renderTabHeader() {
  return (
    this.props.dateArray.map((date, i) => 
      <Tab 
        key={i}
        heading={date.format('DD/MM')} 
        tabStyle={styles.tabStyling} 
        activeTabStyle={styles.activeTabStyle} 
        textStyle={styles.tabTextStyle} 
        activeTextStyle={styles.activeTabTextStyle} 
      >
        <View style={{ backgroundColor: '#EEEEEE', flex: 1 }}>
          <Content contentDate={date.format('YYYY-MM-DD')} />
        </View>
      </Tab>
    )
  );
}

内容组件:

class Content extends Component {
  componentWillMount() {
    console.log('Component Will Mount() ?');
    this.props.loadTransactionByDate({ date: this.props.contentDate });
  }

render() {
  return (
    <View><Text>{this.props.contentDate}</Text></View>
  );
  }

基本上,在MainComponent中有一组选项卡。我注意到一些奇怪的东西,Content将在他们的标签第一次点击或激活时挂载?

第一次的意思是,我们可以单击选项卡索引2并看到控制台登录componentWillMount,然后我们切换到另一个选项卡,如果再次返回选项卡索引2,componentWillMount将不再被触发?

1 个答案:

答案 0 :(得分:8)

首先我想指出你不应该使用componentWillMount生命周期方法,因为它已经在React 16.3的最后一次小更新时被弃用

下列不推荐的生命周期方法列表, (componentWillMount, componentWillReceiveProps, and componentWillUpdate).您可以阅读有关已弃用的生命周期方法的更多信息here

示例生命周期中的辅助工作按预期工作。 componentWillMount只触发一次,因为您的组件只有initial rendered/mounted一次,这就是React的工作原理。

我会用以下方法解决这个问题。

getDerivedStateFromProps生命周期添加到Content组件,这将在组件接收新道具时以及初始安装时触发。

getDerivedStateFromProps(nextProps, prevState) {
  console.log('will log on props change');
  if( nextProps.contentDate !== prevState.contentDate ) {
    return { contentDate: nextProps.contentDate };
    // Notice we return plain object here to update state
  }
  return null;
  // return null when changes are not needed
}

此示例检查contentDate是否已更改,如果是,则将其推送到组件状态。在渲染方法上,您可以通过this.state.contentDate获得它。

render() {
  return (
    <View><Text>{this.state.contentDate}</Text></View>
  );
}

您可以在componentDidUpdate中实现此类似行为,但是您最终会遇到无限循环和更糟糕的性能。但是有可能只是强有力地检查你预期的数据是否真的像你期望的那样改变了。然后,您可以执行setState和组件重新渲染。