简体   繁体   English

组件道具更改后更新Redux存储

[英]Updating redux store after component props change

I'm wondering what the best approach to handle this scenario is in redux and if theres any patterns to favour or avoid: 我想知道在redux中处理这种情况的最佳方法是什么,是否有任何模式值得支持或避免:

I have a 'shopping list' component that is comprised of several sub items, each of which can be modified in a variety of ways. 我有一个“购物清单”组件,该组件由几个子项组成,每个子项都可以通过多种方式进行修改。 I'm also keeping track of the total price of the shopping list which changes every time a sub item is added, removed or modified as well as other factors. 我还跟踪购物清单的总价格,该价格在每次添加,删除或修改子项目以及其他因素时都会更改。

Currently I have a 'Total' component which is subscribed to the store and recalculates the total when any shopping list items (passed to it as props) change. 目前,我有一个“总计”组件,该组件已订阅商店并在任何购物清单项(作为道具传递给它)更改时重新计算总数。 This then saves the recalculated total to the store. 然后,这会将重新计算的总数保存到商店。 Whilst this works and is seemingly more robust than trying to anticipate every action that has an effect on the total, it does mean that the app re-renders twice: firstly when an item changes, then secondly when the total is recalculated. 尽管这种方法行之有效,而且似乎比尝试预期会对总数产生影响的每个动作都更可靠,但这确实意味着该应用程序会重新呈现两次:首先是项更改时,然后是重新计算总数时。

I'm presuming that this is probably not the best approach to the situation and I'm wondering if I can do something a bit neater directly in the shopping list reducer or using some kind of middleware. 我以为这可能不是解决这种情况的最佳方法,而且我想知道是否可以直接在购物清单减少器中使用某些中间件来使事情更整洁。 Any advice would be appreciated. 任何意见,将不胜感激。

- --

The current process can be summarised as: 当前过程可以概括为:

  • User modifies shopping list item 用户修改购物清单项目
  • Action is dispatched, updating the store with the modified shopping list 分派操作,使用修改后的购物清单更新商店
  • New state propagates through app 新状态通过应用传播
  • Price Total component receives new props, recalculates total and dispatches updated total to the store 价格总计组件接收新的道具,重新计算总计并将更新的总计发送到商店
  • New state propagates through app 新状态通过应用传播

The fact that you're using the Total component to calculate the total and then dispatch an action to update the total in the store is what's complicating things. 您正在使用Total组件来计算总数,然后分派操作以更新商店中的总数这一事实使事情变得复杂。 Your total is actually just a derivation of other parts of your state, and does not need to be stored in the state itself. 您的总数实际上只是州的其他部分的派生结果,不需要存储在州本身中。

Assuming you're using react-redux to connect your Total component to your state, you can simply calculate the total in the mapStateToProps part of your connect(). 假设您正在使用react-redux将Total组件连接到您的状态,则可以在connect()的mapStateToProps部分中简单地计算总数。 For example: 例如:

const mapStateToProps = (state, props) => {
  return {
    total: state.shoppingList.reduce((total, item) => total + item.price, 0)
  }
}
export default connect(mapStateToProps)(Total)

(This example assumes state.shoppingList is an array of items, each with a price property. Your situation is probably a little more complex, but the idea is the same.) (此示例假定state.shoppingList是一个项目数组,每个项目都有一个price属性。您的情况可能稍微复杂一些,但想法是相同的。)

This would allow your Total component to access/display the total, but without any of the added complication of having to re-update the state. 这将使您的Total组件可以访问/显示总数,而无需重新更新状态,而不会增加任何复杂性。

For improved performance in these state derivations, have a look at reselect . 为了提高这些状态导数的性能,请查看reselect It allows you to create "memoized" selectors that will only perform their re-calculations when the relevant parts of state have changed, otherwise they will return the derived value from memory. 它使您可以创建“记忆式”选择器,这些选择器仅在状态的相关部分发生更改时才执行其重新计算,否则它们将从内存中返回派生的值。 These selectors can be imported anywhere, so it would make it easy to display the total in other places too, if you ever needed to. 这些选择器可以导入到任何地方,因此,如果需要的话,也可以很容易地在其他位置显示总数。

If i understand correctly i think you should use the component will update function : 如果我理解正确,我认为您应该使用该组件将更新功能:

void componentWillReceiveProps(
  object nextProps
)

Quote from the official doc : 引用官方文档:

"Invoked when a component is receiving new props. This method is not called for the initial render. “当组件接收新道具时调用。初始渲染未调用此方法。

Use this as an opportunity to react to a prop transition before render() is called by updating the state using this.setState(). 以此为契机,通过使用this.setState()更新状态来调用render()之前对prop过渡做出反应。 The old props can be accessed via this.props. 可以通过this.props访问旧的道具。 Calling this.setState() within this function will not trigger an additional render." 在此函数中调用this.setState()不会触发其他渲染。”

This means that when a modification is made to your shopping list, you can calculate the total in the componentWillReceiveProps function without triggering a second render. 这意味着,对购物清单进行修改后,您可以在componentWillReceiveProps函数中计算总数,而无需触发第二次渲染。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM