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 中的扩展运算符的主要内容,如果未能解决你的问题,请参考以下文章
React/Redux - 使用扩展运算符将对象添加到数组的开头
如何在 react-redux 中使用扩展运算符修改索引处的特定对象?