简体   繁体   English

Redux:在reducer做deep-compare,如果没有变化就返回原来的state是不是很常见?

[英]Redux: Is it common to do deep-compare at reducer and return original state if no change?

  • Action: fetch an array of data from the server.操作:从服务器获取一组数据。
  • Reducer: save an array of data to store. Reducer:保存一个数据数组来存储。

My reducer saves the array of data in the expected immutable fashion:我的减速器以预期的不可变方式保存数据数组:

return {
  ...state,
  arrayOfData: fetchedArrayOfData,
};

The fetch action happens periodically, but the content of the array remains the same most of the time.获取操作会定期发生,但数组的内容大部分时间保持不变。 However, since a new reference is saved each time, the selector for this data will be considered "changed", and doesn't memoize well if used as an input for creatorSelector .但是,由于每次都会保存一个新引用,因此该数据的选择器将被视为“已更改”,并且如果用作creatorSelector的输入则不能很好地记忆。

The only solution I can think of is to perform a deep-compare at the reducer, and if the contents are the same, simply return the original state:我能想到的唯一解决办法是在reducer进行deep-compare,如果内容相同,直接返回原来的state:

return state;

If this common practice/pattern?如果这种常见的做法/模式?

Note: I tried to look around, and most projects are doing the same thing that I was doing (ie return new state object), which will do not memoize well and causes selector transformations to run.注意:我试着环顾四周,大多数项目都在做我正在做的事情(即返回新的 state 对象),这不会很好地记忆并导致选择器转换运行。

There are some solutions like using immutableJS as mentioned in the comments but you can return your state conditionally by comparing your fetchedArrayOfData with the last one (which is stored in your state).有一些解决方案,如评论中提到的使用immutableJS ,但您可以通过将fetchedArrayOfData与最后一个(存储在您的状态中)进行比较,有条件地返回您的 state 。

Assume there is a comparison function that gives two arrays and compares them.假设有一个比较 function 给出两个 arrays 并比较它们。

In the reducer:在减速器中:

const previousFetchedData = state.fetchedArrayOfData;
const newFetchedData = action.payload.fetchedArrayOfData;

const resultOfComparision = isSameArray(previousFetchedData, newFetchedData) // true or false

if (resultOfComparision) { // case of same arrays
  return state
} else { // case of different arrays
  ...state,
  arrayOfData: fetchedArrayOfData,
};

Note 1: you can create your own comparison function but there are many nice ones in this post of StackOverflow which you can use them.注意 1:您可以创建自己的比较 function,但 StackOverflow 的这篇文章中有很多不错的比较,您可以使用它们。

Note 2: using immutableJs and conditional returning data from reducer is common(in such scenario) and don't worry about using them.注意 2:使用immutableJs和从 reducer 有条件返回数据是很常见的(在这种情况下),不要担心使用它们。

Note 3: You can also compare your data at the component level by using the traditional way with shouldComponentUpdate .注意 3:您还可以使用传统方式与shouldComponentUpdate在组件级别比较数据。

Node 4: using middlewares like redux-saga will be useful, you can also implement the isSameArray function in the saga and then dispatch the proper action.节点4:使用像redux-saga这样的中间件会很有用,你也可以在saga中实现isSameArray function 然后派发适当的动作。 read more on saga documentation.阅读更多关于saga文档的信息。

Note 5: The best solution (in my thought) is to handle this case on the backend services with 304 status which means Not modified .注意 5:最好的解决方案(在我看来)是在后端服务上以304状态处理这种情况,这意味着Not modified then you can easily determine the right action according to the response status.然后您可以根据响应状态轻松确定正确的操作。 more info on MDN documentation.有关MDN文档的更多信息。

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

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