ComponentWillMount 仅第一次触发?

Posted

技术标签:

【中文标题】ComponentWillMount 仅第一次触发?【英文标题】:ComponentWillMount only trigger for first time? 【发布时间】:2018-09-27 15:13:56 【问题描述】:

主组件:

<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 第一次点击或激活他们的标签时会安装一些相当奇怪的东西?

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

【问题讨论】:

不确定我是否记错了,但是当您切换选项卡时,您的组件已经挂载,因此不会再次挂载。它可能会调用componentWillUpdate(),但不会调用componentWillMount(); 您可以添加您正在使用的 Tabs 包吗? @PritishVaidya:我可以知道您所说的 Tabs 的 Tabs 包包含在此问题的第一部分中吗 @GuiHerzog:我不这么认为,因为我已经为我的Content 组件中的每个组件生命周期方法制作了控制台日志。显然这些组件生命周期只在第一次加载时触发,一旦再次访问相同的选项卡,这些组件生命周期方法都不会被触发 在此处查看有关此查询的更新github.com/GeekyAnts/NativeBase/issues/1798 【参考方案1】:

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

这里列出了已弃用的生命周期方法, (componentWillMount, componentWillReceiveProps, and componentWillUpdate).您可以阅读更多关于已弃用的生命周期方法here。

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

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

在 Content 组件中添加 getDerivedStateFromProps 生命周期,当组件接收到新的 props 以及初始挂载时都会触发。

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

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

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

您可以通过在componentDidUpdate 中实现这一点来实现类似的行为,但是您最终面临无限循环和更糟糕的性能的更大风险。但是有可能只是严格检查您所期望的数据是否确实如您所期望的那样发生了变化。然后你可以做setState 和组件重新渲染。

【讨论】:

getDerivedStateFromProps() 被定义为实例方法,将被忽略。相反,将其声明为静态方法

以上是关于ComponentWillMount 仅第一次触发?的主要内容,如果未能解决你的问题,请参考以下文章

react生命周期函数

ComponentwillMount 被调用两次

iOS UILocalNotification 设置为每天触发一次,每两天触发一次,并且仅在星期日触发

mapEventToState 仅触发一次

react生命周期

iOS Safari Mobile 不会仅触发一次页面显示触发