javascript - 如何在不使用扩展运算符的情况下更改 Redux 状态的子切片

标签 javascript redux

我需要更新我的状态的一个切片,而不更新整个切片;仅子切片。我见过其他人结合 reducer 来实现这一点,但我还没有弄清楚如何在我的项目中做到这一点。 Redux.js.org 将其显示为另一种实现方式:

function updateVeryNestedField(state, action) {
    return {
        ....state,
        first : {
            ...state.first,
            second : {
                ...state.first.second,
                [action.someId] : {
                    ...state.first.second[action.someId],
                    fourth : action.someValue
                }
            }
        }
    }
}

不幸的是,我的项目是用 JavaScript 编写的。我如何在没有扩展运算符的情况下使用普通的 javascript 复制它?我已经尝试使用 Object.assign 进行一些变体,但无法使其正常工作。

最佳答案

正如您所提到的,您可以使用 Object.assign 代替 spread:

{...state, x: 1}

应该给你相同的结果

Object.assign({}, state, {x: 1})

请注意,空对象是 Object.assign 的第一个参数。其作用是将 state 中的值复制到一个新的空对象中,然后将 {first: 1} 中的值复制到新对象中。

例如:

var a = { x: 1, y: 2}
var b = {...a, y: 3 }
console.log(a); // { x: 1, y: 2 }
console.log(b); // { x: 1, y: 3 }

相当于

var c = { x: 1, y: 2 }
var d = Object.assign({}, a, { y: 3 });
console.log(c); // { x: 1, y: 2 }
console.log(d); // { x: 1, y: 3 }

重要的是,ac 都没有改变。 bdy 提供了新值。

对于嵌套对象,您可以重复此过程:

function updateVeryNestedField(state, action) {
    return Object.assign({}, state, {
        first : Object.assign({}, state.first, {
            second : Object.assign({}, state.first.second, {
                [action.someId] : Object.assign({},
                    state.first.second[action.someId],
                    { fourth : action.someValue }
                )
            })
        })
    });
}

var oldState = { first: { second: { 'anId': { fourth: 3 } } } };
var newState = updateVeryNestedField(oldState, { someId: 'anId', someValue: 5 });
console.log(oldState.first.second.anId.fourth); // 3
console.log(newState.first.second.anId.fourth); // 5

但是,要获得完整的 ES2015 支持,您也无法 use computed keys 。因此,您应该在 return 语句之前构建一些对象。例如:

function updateVeryNestedField(state, action) {
    // Create a temporary object to avoid use of computed keys
    var updatedSecond = Object.assign({}, state.first.second);
    updatedSecond[action.someId] = Object.assign({}, state.first.second[action.someId], {
        fourth: action.someValue
    });
    return Object.assign({}, state, {
        first : Object.assign({}, state.first, { second : updatedSecond })
    });
}

var oldState = { first: { second: { 'anId': { fourth: 3 } } } };
var newState = updateVeryNestedField(oldState, { someId: 'anId', someValue: 5 });
console.log(oldState.first.second.anId.fourth); // 3
console.log(newState.first.second.anId.fourth); // 5

关于javascript - 如何在不使用扩展运算符的情况下更改 Redux 状态的子切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43825071/

相关文章:

javascript - Highcharts 重叠类别标签

javascript - Jquery 焦点不起作用/滚动

javascript - 无法输入 react 输入文本字段 - onChange 无法正常工作

javascript - 使用 Redux 容器组件模式渲染动态数量的 React 子组件的稳健方法是什么?

javascript - CSS/JS 调整图形大小以适合图像大小

javascript - 为什么 array.sort 在 JavaScript 中不起作用?

javascript - 如何使用 CSS 类有选择地更改文本?

javascript - 尝试使用 componentWillReceiveProps 更改按钮颜色

javascript - 在 redux 中进行 fetch 调用时处理错误

javascript - 使用 react redux 编辑表值