【问题标题】:Force component to remount with new props强制组件使用新道具重新安装
【发布时间】:2019-11-11 19:01:01
【问题描述】:

我正在使用react-native@0.60.5react-native-router-flux@4.0.6。我正在尝试从selectItems 组件跳回newCollection,这是一个表单。

我创建了一个组件,它呈现带有复选框的项目列表。当用户点击 Done 按钮时,我使用 setParams 将所选项目作为道具传递——就像这样:

 // SelectItems.js
 this.props.navigation.setParams({
   rightTitle: 'Done',
   onRight: () =>
     Actions.jump('newCollection', {
       selectedItems: this.state.taggedItems,
     }),
 });

这很好用,当newCollection 组件呈现时,我可以在我的表单中显示来自this.props.selectedItems 的选定项目列表。

当组件挂载时,我需要使用this.props.selectedItems 调用动作创建者。

下面是动作:

      // NewCollection.js

      // Map the items selected in the the `selectItems` component
      // and invoke an action

      var fetchTaggedItems = new Promise((resolve, reject) => {
        this.props.taggedItemsFetch(this.props.taggedItems.map(x => x.uid));
        resolve(this.props.matchingOutfits);
      });

      fetchTaggedItems.then(x => {
            console.log(x);
            alert('done!');
          });

现在,我的理解是组件在收到这些新道具时应该重新安装,但它不会。使用componentDidMount 中的日志,我看到它只安装在第一个条目上。

上面的代码我试过了:

  • 使用 Actions.refresh() 而不是 Actions.jump() — 没有任何反应
  • 使用static onEnter() 更新组件状态并强制重新挂载——无法访问this.state
  • render() 内部调用动作创建者——无限循环
  • 在状态中设置布尔 calledActionCreator 标志以防止无限循环 - 不起作用 — 将 this.propscomponentDidUpdate() 中的 prevProps 进行比较 — 错误:超出最大更新深度

我开始认为这是 React Native Router Flux 的一个错误。

【问题讨论】:

  • 请也提供有关您的其他组件的更多信息
  • 我添加了代码来展示我如何调用动作创建者。还有什么有用的吗?

标签: javascript reactjs react-native react-redux react-native-router-flux


【解决方案1】:

希望这段代码对您有所帮助,它是我项目的一部分,我需要强制更新道具更改,在此代码中您可以触发道具更改以及它必须做什么。 注意:当您使用 setState 时,您的组件将呈现。在这个生命周期中,如果一个 props 发生了变化,它会调用 setState 来重新渲染组件。

        if (this.props !== prevProps) {
            this.setState({
               // do somethings
            })
        }
    }

【讨论】:

  • 谢谢 - 我在 componentDidUpdate() 中试过这个,但我达到了最大更新深度。
  • 如果你不使用它,ifif 语句总是正确的,它会达到最大更新深度。 @owiewio
  • 抱歉,您能否进一步澄清一下?你的意思是如果我不包含else 声明?
【解决方案2】:

好的,经过大量挖掘和实验,我找到了一个可行的解决方案(至少在表面上)。

这里是:

// NewCollection.js
  static onEnter() {
    Actions.refresh({key: Math.random()});
  }

使用普通的Actions.refresh() 重新挂载组件似乎没有任何效果。提供随机密钥作为道具似乎会强制更新。

我确信这不是最优雅的解决方案,但它现在似乎可行。

【讨论】:

    猜你喜欢
    • 2016-06-17
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 2017-06-11
    相关资源
    最近更新 更多