如何在Redux Reducer中以不变的方式交换数组元素? [英] How do I swap array elements in an immutable fashion within a Redux reducer?

查看:68
本文介绍了如何在Redux Reducer中以不变的方式交换数组元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关的Redux状态由代表图层的对象数组组成.

The relevant Redux state consists of an array of objects representing layers.

示例:

let state = [
    { id: 1 }, { id: 2 }, { id: 3 }
]

我有一个名为moveLayerIndex的Redux动作:

I have a Redux action called moveLayerIndex:

actions.js

export const moveLayerIndex = (id, destinationIndex) => ({
    type: MOVE_LAYER_INDEX,
    id,
    destinationIndex
})

我希望reducer通过交换数组中元素的位置来处理动作.

I would like the reducer to handle the action by swapping the position of the elements in the array.

reducers/layers.js

const layers = (state=[], action) => {
    switch(action.type) {
        case 'MOVE_LAYER_INDEX':

/*我应该在这里输入以下内容以通过以下测试*/

/* What should I put here to make the below test pass */

        default:
         return state
    }
}

该测试验证Redux reducer是否以不变的方式交换数组的元素.

The test verifies that a the Redux reducer swaps an array's elements in immutable fashion.

深度冻结用于检查初始状态是否没有任何突变.

Deep-freeze is used to check the initial state is not mutated in any way.

我如何通过此考试?

test/reducers/index.js

import { expect } from 'chai'
import deepFreeze from'deep-freeze'

const id=1
const destinationIndex=1

 it('move position of layer', () => {
    const action = actions.moveLayerIndex(id, destinationIndex)
    const initialState = [
        {
          id: 1
        },
        {
          id: 2
        },
        {
          id: 3
        }
    ]
    const expectedState = [
        {
          id: 2
        },
        {
          id: 1
        },
        {
          id: 3
        }
    ]
    deepFreeze(initialState)
    expect(layers(initialState, action)).to.eql(expectedState)
 })

推荐答案

不变更新的关键思想之一是,尽管您从不直接修改原始项目,但进行复制并对其进行变异,然后将其退还.

One of the key ideas of immutable updates is that while you should never directly modify the original items, it's okay to make a copy and mutate the copy before returning it.

请记住,此功能应该执行您想要的操作:

With that in mind, this function should do what you want:

function immutablySwapItems(items, firstIndex, secondIndex) {
    // Constant reference - we can still modify the array itself
    const results= items.slice();
    const firstItem = items[firstIndex];
    results[firstIndex] = items[secondIndex];
    results[secondIndex] = firstItem;

    return results;
}

我为Redux文档写了一个名为构造Reducers-不可变的更新模式的部分提供了一些有关更新数据的方式的示例.

I wrote a section for the Redux docs called Structuring Reducers - Immutable Update Patterns which gives examples of some related ways to update data.

这篇关于如何在Redux Reducer中以不变的方式交换数组元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆