首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Redux还原器中以不变的方式交换数组元素?

如何在Redux还原器中以不变的方式交换数组元素?
EN

Stack Overflow用户
提问于 2016-12-13 17:52:42
回答 3查看 6.1K关注 0票数 8

相关的Redux状态由表示层的对象数组组成。

示例:

代码语言:javascript
复制
let state = [
    { id: 1 }, { id: 2 }, { id: 3 }
]

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

actions.js

代码语言:javascript
复制
export const moveLayerIndex = (id, destinationIndex) => ({
    type: MOVE_LAYER_INDEX,
    id,
    destinationIndex
})

我希望还原器通过交换数组中元素的位置来处理操作。

reducers/layers.js

代码语言:javascript
复制
const layers = (state=[], action) => {
    switch(action.type) {
        case 'MOVE_LAYER_INDEX':

/*我应该在这里放什么让下面的测试通过*/

代码语言:javascript
复制
        default:
         return state
    }
}

测试验证Redux还原器是否以不可变的方式交换数组的元素。

深度冻结用于检查初始状态是否以任何方式发生变异.

我如何通过这个测试?

test/reducers/index.js

代码语言:javascript
复制
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)
 })
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-12-13 17:57:12

不可变更新的关键思想之一是,虽然您不应该直接修改原始项,但在返回之前可以复制并修改副本。

考虑到这一点,这个函数应该做您想做的事情:

代码语言:javascript
复制
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文档编写了一个名为结构减速器.不变的更新模式的部分,其中给出了一些更新数据的相关方法的示例。

票数 10
EN

Stack Overflow用户

发布于 2017-04-20 03:48:31

您可以使用映射函数进行交换:

代码语言:javascript
复制
function immutablySwapItems(items, firstIndex, secondIndex) {
    return items.map(function(element, index) {
        if (index === firstIndex) return items[secondIndex];
        else if (index === secondIndex) return items[firstIndex];
        else return element;
    }
}

采用ES2015风格:

代码语言:javascript
复制
const immutablySwapItems = (items, firstIndex, secondIndex) =>
  items.map(
    (element, index) =>
      index === firstIndex
        ? items[secondIndex]
        : index === secondIndex
        ? items[firstIndex]
        : element
  )
票数 4
EN

Stack Overflow用户

发布于 2020-03-17 09:48:40

另外两个答案没有什么问题,但我认为用ES6做这件事有一个更简单的方法。

代码语言:javascript
复制
const state = [{
  id: 1
}, {
  id: 2
}, {
  id: 3
}];

const immutableSwap = (items, firstIndex, secondIndex) => {
  const result = [...items];
  [result[firstIndex], result[secondIndex]] = [result[secondIndex], result[firstIndex]];
  return result;

}

const swapped = immutableSwap(state, 2, 0);

console.log("Swapped:", swapped);
console.log("Original:", state);

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41127548

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档