Redux reducer 中的扩展运算符

Posted

技术标签:

【中文标题】Redux reducer 中的扩展运算符【英文标题】:the spread operator in Redux reducer 【发布时间】:2019-03-13 02:49:12 【问题描述】:

我想了解扩展运算符在 Redux 状态下的作用?

我回答了这个问题Purpose of the Spread syntax in React-Redux Reducers,但由于某种原因我不相信答案。

谁能用非常简单的语言解释一下我们为什么要做这样的事情

  case WHATEVER:
      return 
        ...state,
        DateSucess: action.payload,

不仅仅是

 case WHATEVER
  return 
   DataSucess: action.payload

【问题讨论】:

如果 reducer state 是一个具有多个键的对象,例如:DataSucess: '', a: '', b: '', c: '',并且如果您只返回一个键值,那么所有其他键值对都将丢失。扩展运算符的目的是返回整个对象并更新一个值。 如果它只是一个布尔值怎么办?并且它独立于所有其他键值对? @MayankShukla 你能在答案部分详细解释一下吗? Spread Syntax ES6的可能重复 【参考方案1】:

扩展运算符只返回与 is 关联的数组或 obj 的副本。看看下面的例子

const abc = 
  'first_key':1,
  'second_key':2,


const newObj=...abc //will COPY abc

const newObjWithNewKey = ...abc,  'first_key':'01 first','new_key':'007' // will COPY abc and value of first_key will be replaces with new value as it exists. will add new keyvalue pair new_key.

console.log("abc",abc,"newObj",newObj,"newObjWithNewKey",newObjWithNewKey)

现在在 redux 中,如果您只是 return new payload,那么您将丢失其他状态值。 但是如果你使用...,意味着你告诉js复制现有状态并更新指定keys的值,如果没有键则添加新的

【讨论】:

【参考方案2】:

展开运算符的作用与 ES6 中的相同,但行为仍然相同(检查 MDN docs)。

关于使用 ...state 的动机很简单:保持旧状态并添加或覆盖 DateSucess 属性。

那么让我们说:

const state = foo: 'bar', DateSucess: 'oldDateSuccess', zip: 'zap'

如果您不使用 spread 新的 state 值将只是 DateSucess 并且您将丢失 foo 和 zip 值,使用 spread 您只是覆盖 DateSucess 保持其余值不变。

这个价差相当于Object.assign

return Object.assign(oldState, DateSucess: 'newDateSucess')

【讨论】:

【参考方案3】:

假设您的状态结构如下所示:

const initialState = 
    DateSucess: ' ',
    DateFailure: ' '

那么,有了这个状态,现在我们编写一个 reducer 并且......

reducer 是一个纯函数,它接受前一个状态和一个 动作,并返回下一个状态。

在reducer中,我们进行一些计算并返回下一个状态。请记住,我们不会改变状态。我们使用 Object.assign() 创建一个副本。

Object.assign(state, DateSucess: action.payload) 也是错误的:它会改变第一个参数。您必须提供一个空对象作为第一个参数。像这样:

return Object.assign(, state,  DateSucess: action.payload)    

您还可以启用对象扩展运算符提案以改为编写 ...state, ...newState 。在你的情况下,它看起来像:

return ...state, DateSucess: action.payload

欲了解更多信息:https://redux.js.org/basics/reducers

【讨论】:

或者如果你的有效载荷值匹配你的返回值return ...state, ...action.payload ;【参考方案4】:

如果你正在使用 react 并询问 react-redux,这可能是你的答案-

我们不应该改变 reducer 内部的状态。使用扩展运算符,我们复制先前的状态并更新它的副本。因此,我们不会改变我们的 prev 状态,同时更新它。这就是展开算子的作用。

现在,可能会出现另一个问题。为什么我们不能在 reducer 中发生变异。嗯,这对我来说是一个“反应”的事情。 React 创建虚拟 dom 来处理 dom 的操作。如果你改变内部状态,dom 和 virtual dom 的同步可能会中断,事情会变糟。

希望此描述对您有所帮助。

【讨论】:

以上是关于Redux reducer 中的扩展运算符的主要内容,如果未能解决你的问题,请参考以下文章

Redux:在二维数组上使用扩展运算符

扩展运算符不适用于基于 Redux/ES6 的示例

React/Redux - 使用扩展运算符将对象添加到数组的开头

如何在 react-redux 中使用扩展运算符修改索引处的特定对象?

带有 object.assign 的 Redux reducer 在同名的顶部键中创建键

Redux: Reduced - 如何在嵌套数组的递归过程中避免对象不可扩展错误?