javascript - 我们应该在reducer中比较新状态和旧状态吗

标签 javascript reactjs redux react-redux

我在 reducer 函数中使用扩展运算符,所以当我调度 Action 时发生了什么,然后它正在创建新状态(obj),即使旧状态与新状态相同,所以它正在重新渲染 react 组件。
将新状态与旧状态进行比较是否是一种好方法,因为对象可能很复杂?深度比较?

const initialState = {};

export const reducer = (state = initialState, action: any = {}): any => {
  if (action.type === ActionTypes.RC) {
    return {
      ...state,
      ...action.config,
    };
  }
  return state;
};
还是 redux 在 mapStateToProps 中为您开箱即用?

最佳答案

这里有几点值得注意。
React Redux 使用严格相等(引用相等)作为默认的比较方法。 Redux 状态的不可变特性意味着对深度嵌套属性的任何更改都要求其所有祖先都必须是新的对象引用。
如果您更新 a.b.c然后 aa.b必须是新对象。假设您有一个同级属性树,例如 a.d.e .当您更新 a.b.c它会导致 a成为新的对象引用,但 a.da.d.e是相同的。如果您有一个组件只需要了解 a.d那么它应该不需要重新渲染以响应您的 a.b.c改变。
这就是为什么 很重要的原因。每个组件应该只从状态 中选择它需要的最少信息。 .你应该 connect more individual components而不是从 state 中选择大量信息并通过 props 向下传递。您可以use multiple useSelector hooks in the same component选择小的、颗粒状的状态。

你确实有能力customize the equality comparison通过将比较函数作为第二个参数传递给 useSelector钩。
如果你有一个组件订阅了这个 reducer 控制的状态,那么你可以使用 shallowEqual react-redux 中包含的函数包裹。我不确定您问题中的 reducer 是您的根 reducer 还是您传递给 combineReducers 的东西.我假设它只是一件。
假设这是一个属性 settings你有一些updateSettings将新设置与现有设置合并的操作。然后,当您有一个需要访问设置的组件时,您可以这样做:

import { shallowEqual, useSelector } from 'react-redux'
const settings = useSelector(state => state.settings, shallowEqual);
这意味着组件只会在某些设置实际更改时重新渲染,即使 state.settings是一个新对象。它正在对 state.settings 的当前值进行浅层比较和上一个。
可以使用像 lodash 的 isEqual 这样的深度等于比较。但我不明白你为什么需要它,因为这个 reducer 正在制作一个浅拷贝。如果您需要在任何地方进行昂贵的检查,那么在您 dispatch 之前进行似乎更合乎逻辑。组件中的操作或从 reducer 返回新对象之前的操作,而不是每次调用 useSelector钩。
您询问是否应该在返回新的 state 之前检查 reducer 中的更改。目的。这是个好主意,它实际上是由 combineReducers 创建的组合 reducer 。确实如此,尽管它只检查浅层相等。见 lines 177-201 of the source code .如果所有单独的属性 reducer 返回与以前相同的对象,那么它将返回先前组合的 state为了维护对象引用。

关于javascript - 我们应该在reducer中比较新状态和旧状态吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67683255/

相关文章:

javascript - 设置 useState 对象值时使用 prop value

javascript - 在 react 子组件中操作 Prop 的 redux-react 方法是什么

react-native - 如何延迟 Redux Persist Gate 的 SplashScreen?

Redux/Reselect - 选择器重用

reactjs - 使用 React 更新基于地理位置的 Google map

javascript - 如何判断子对象中的属性是否存在?

javascript - 如何在 Angular js中将数据从工厂传递到 Controller ?

javascript - 影响 d3.mouse 点的父 css 变换

javascript - 将 jQuery 创建的元素附加到 vanilla js?

css - 如何在 React Native 中对齐同一 Flex 行上的 Textinput 输入? (动态地)