gpt4 book ai didi

javascript - reducer 组合 - 为什么我们需要使用 Object.assign() 重新分配待办事项,为什么不直接调用另一个 reducer 呢?

转载 作者:行者123 更新时间:2023-11-28 18:06:22 25 4
gpt4 key购买 nike

在这个 reducer 组合示例中,为什么我们不能只返回我们正在调用的 reducer ?这意味着,在 todoApp reducer 中,无论是 ADD_TODO 还是 TOGGLE_TODO,我们都使用另一个 reducer :todos 。我明白那个。但我不明白为什么我们不能将 todoApp 中的情况设置为

function todoApp(state = initialState, action) {
switch (action.type) {
case ADD_TODO:
case TOGGLE_TODO:
return todos(state.todos, action)

与我们这里的相比:

function todoApp(state = initialState, action) {
switch (action.type) {
case ADD_TODO:
case TOGGLE_TODO:
return Object.assign({}, state, {
todos: todos(state.todos, action)
})

特别是因为 todos reducer 正在返回完整的新状态对象,对吧?我们不是仍然遵循redux规则,不通过返回第二个reducer的结果来修改状态吗?

function todos(state = [], action) {
switch (action.type) {
case ADD_TODO:
return [
...state,
{
text: action.text,
completed: false
}
]
case TOGGLE_TODO:
return state.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: !todo.completed
})
}
return todo
})
default:
return state
}
}

function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
case ADD_TODO:
case TOGGLE_TODO:
return Object.assign({}, state, {
todos: todos(state.todos, action)
})
default:
return state
}
}

最佳答案

你问的是为什么

case TOGGLE_TODO:
return Object.assign({}, state, {
todos: todos(state.todos, action)
})

...不能只是这样...

case TOGGLE_TODO:
return todos(state.todos, action)

您必须注意您正在使用的 reducer 的特定上下文中状态的形状

  • todo 的状态形状为 [Todo] – 其中 [Todo] 是一个数组 待办事项

  • todoApp 的状态形状为 {todos: [Todo]}

如果您要使用建议的代码

case TOGGLE_TODO:
return todos(state.todos, action)

知道 todos 将返回 [Todo],您将替换您的 todoApp 状态...

{todos: [Todo]}

...与

[Todo]

...这不是正确的形状。

<小时/>

So if the shape were the same this would be ok, I wouldn't be modifying the state otherwise, correct? – Anna Garcia 25 mins ago

正确,但他们在本例中使用 Object.assign 的原因是一种具有前瞻性的最佳实践。

你可以这么做

case TOGGLE_TODO:
return {todos: todos(state.todos, action)}

但是,可以合理地认为您的应用程序将具有需要关心的其他状态“切片”,而不仅仅是 todos。在这种情况下,TOGGLE_TODO 操作仅作用于 todos 切片。请注意更新 todos 的方式不会破坏此上下文中的所有其他现有属性。

假设我们的应用程序还有另外两个状态片:foobar。如果我们这样做...

// where state = {foo: 1, bar: 2, todos: [ ... ]}
case TOGGLE_TODO:
return {todos: todos(state.todos, action)}

那么我们只返回 {todos: ...}foobar 属性/值已被删除!不好!<​​/p>

相反,我们必须小心保留其他状态条目,并且对我们想要修改的状态进行操作

// where state = {foo: 1, bar: 2, todos: [ ... ]}
case TOGGLE_TODO:
return Object.assign({}, state, {todos: todos(state.todos, action)})

现在我们就回来

{foo: 1, bar: 2, todos: newTodosArray}

这正是我们想要的 - 所有 foobartodos 属性仍然在 todoApp 中> 状态。

<小时/>

对象传播语法

有一项支持对象扩展语法的提案,这可以将 Object.assign 示例简化为

case TOGGLE_TODO:
return {...state, todos: todos(state.todos, action)}

但是在它进入 ECMAScript 之前,您必须使用 transform-object-rest-spread 对其进行 babelify。

关于javascript - reducer 组合 - 为什么我们需要使用 Object.assign() 重新分配待办事项,为什么不直接调用另一个 reducer 呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42496487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com