ComponentWillMount仅在第一次触发?

Sui*_*eep 1 lifecycle components react-native 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>
    )
  );
}
Run Code Online (Sandbox Code Playgroud)

内容组件:

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>
  );
  }
Run Code Online (Sandbox Code Playgroud)

基本上,在MainComponent中有一组选项卡.我注意到一些相当奇怪的东西Content会在他们的标签第一次点击或激活时安装?

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

Jim*_*ala 8

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

下面列出了已弃用的生命周期方法, (componentWillMount, componentWillReceiveProps, and componentWillUpdate).您可以在此处阅读有关已弃用的生命周期方法的更多信息.

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

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

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

static 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
}
Run Code Online (Sandbox Code Playgroud)

此示例检查contentDate已更改的内容,如果是,则将其推送到组件-state中.在渲染方法上你可以得到它this.state.contentDate.

render() {
  return (
    <View><Text>{this.state.contentDate}</Text></View>
  );
}
Run Code Online (Sandbox Code Playgroud)

你可以通过实现它来实现类似的行为,componentDidUpdate但是你有更大的风险来结束无限循环和更糟糕的性能.但是有可能只是强有力地检查你预期的数据是否真的如你所期望的那样改变了.然后你可以做setState和组件重新渲染.