Redux componentDidUpdate使用下一个道具

时间:2019-01-18 14:25:53

标签: reactjs redux

componentDidUpdate中派生数据,将其推入redux存储,然后又使用该数据进一步派生更多数据,然后再次将其推入redux存储的最佳实践是什么?

鉴于redux是同步的,我希望能够在执行分派后立即访问更新的商店,但是我假设由于它仍位于componentDidUpdate中,因此道具不会使用新的商店数据进行更新通过mapStateToProps。即我尝试-

componentDidUpdate(){
    this.determineAndStoreA()
    this.doSomethingElse(this.props.A) // hoping this would be the updated A
}

this.props.A仍然是旧值

我应该更像-

componentDidUpdate(){
    const a = this.determineA()
    this.storeA(a);
    this.doSomethingElse(a) // using a local copy of A
}

通过进一步的挖掘,我在https://github.com/reduxjs/react-redux/issues/291中发现了一个类似的问题。 Dan建议对减速器中的动作做出反应,但是感觉就像我现在必须结合确定A,从A确定B,同时存储A和B的逻辑?

3 个答案:

答案 0 :(得分:1)

我想我明白你在做什么。首先,让我尝试更全面地描述我认为您正在处理的方案。

您的商店中有ABC是从AB派生的,因此,如果A发生变化,您想重新推导C并将其放入商店。然后,您可以拥有从EC派生的组件道具D。动作x更改了A,现在您需要CE的新值,并且很难一步一步地完成而使简化器变得过于复杂。

我在这种情况下使用了三种主要方法,我建议哪种方法取决于情况的具体情况。所有这些只是确定C的方式/时间/位置的不同方法(并且可以扩展为E之类的进一步推导)。

方法1 在专门用于处理动作副作用的中间件中计算C

这是与您现有的方法最相似的方法。它只是将其移出组件,因此您无需与商店之间的交互以及生命周期方法何时接收新信息进行对抗。对于这种方法,我将使用Redux Saga并让其处理C以响应动作x并分派该动作以用C的新值更新商店。这很容易做到(如果您已经超过了最初的Redux Saga学习曲线),因为Redux Saga在商店更新后会收到操作。这种方法的主要缺点是您的商店暂时处于不一致状态,其中C尚未反映对A的更改。在某些情况下,这很重要,在某些情况下则无关紧要。另一个潜在的缺点是,如果您尚未使用Redux Saga,那么一开始可能会有点吓人,因为在使用Redux Saga时使用生成器函数和yield以及整个思维方式可能会有些陌生(但我真的很喜欢在复杂的异步情况下使用Redux Saga。

方法2 在操作创建者中计算C

这通常涉及使用thunk来对动作x进行初始响应,然后thunk可以从存储中获取B,计算C并使用包含以下内容的有效负载调度一个动作:分为两部分-一套由化简器用于A,另一套由化简器用于C。这种方法的主要缺点是,如果C(即AB)的依存关系可以通过多种方式改变,这将成为一种复杂的组织方式,但是对于在某些情况下它可以正常工作。我主要从其他方法转向其他两种方法。

方法3 请勿在您的商店中放置C

如果C完全来自商店中的其他事物,那么它实际上并不需要在商店中。 C只是您商店中其他信息的视图。您可以为此使用选择器。如果派生C的开销很大,请使用记忆选择器。在还具有从EC派生的D的更复杂的情况下,E的选择器可以在获取{ {1}}。除非有令人信服的理由将C放入商店,否则我通常会采用这种方法。这种方法使您的减速器保持简单和独立,同时使商店保持一致状态。

其他方法

还有其他方法可以执行此操作,但是上述3种方法是我自己实际使用的方法。另一种方法是拥有一个可以利用其他减速器的减速器。在这种方法中,DC的化简器将由化简器使用,然后化简器计算A并返回所有三条信息的状态。有一些软件包可以简化以这种方式组成reducer的过程,但是我没有使用它们,因为我对这种方法不是很感兴趣。对我来说,感觉这种复杂性的位置不对。

答案 1 :(得分:0)

在Redux将值推入存储并触发对组件的另一次更新的同一周期中,您将不会获得更新的道具。

您真的需要从componentDidUpdate触发这两个操作吗?

您可以做的是创建一个新操作,该操作从您存储A值的操作中触发。

类似的东西

store.dispatch(saveValueA()).then(() =>
  doSomeAction()
);

答案 2 :(得分:0)

每次A更改并调用componentDidUpdate时,组件都会重新呈现。

然后您可以执行以下操作:

componentDidUpdate(prevProps){

    const hasAChanged = this.props.A !=== prevprops.A;

    if (hasAChanged) {
        this.determineAndStoreA()
    } else {
        this.doSomethingElse(this.props.A)
    }
}

我不确定您要做什么,希望对您有所帮助。