javascript - 对象无法正确复制

标签 javascript redux

在尝试用测试覆盖我的 React/Redux 应用程序时,我遇到了以下问题:我的 reducer 更改了初始状态对象,尽管我在 reducer 内复制了该对象。

这是 reducer 代码:

[actionTypes.POINT_REMOVE]: (state, action) => {
    const newState = { ...state }
    const { byId, ids } = newState;
    const { id } = action;

    ids.splice(ids.indexOf(id), 1);
    delete byId[id];

    return {
      ...newState,
      byId: {
        ...byId
      },
      ids: [...ids],
    };
  },

这是测试代码:

describe('with non-empty state', () => {
    const firstId = 123;
    const secondId = 456;
    const thirdId = 789;

    const initialState = {
      byId: {
        [firstId]: {
          id: firstId,
        },
        [secondId]: {
          id: secondId,
        },
        [thirdId]: {
          id: thirdId,
        },
      },
      ids: [firstId, secondId, thirdId],
    };

    describe('on POINT_REMOVE action', () => {
      it('should remove point', () => {  
        const expectedState = {
          byId: {
            [secondId]: {
              id: secondId,
            },
            [thirdId]: {
              id: thirdId,
            },
          },
          ids: [secondId, thirdId],
        };

        const action = actionCreators.removePoint(firstId);
        const actualState = pointsReducer(initialState, action);

        expect(actualState).toEqual(expectedState);
      });
    });

    describe('on POINT_OREDER_CHANGE action', () => {
      it('should change order of elements in ids array', () => {
        const oldIndex = 1;
        const newIndex = 2;

        console.log(initialState);

        const expectedState = {
          byId: {
            [firstId]: {
              id: firstId,
            },
            [secondId]: {
              id: secondId,
            },
            [thirdId]: {
              id: thirdId,
            }
          },
          ids: [firstId, thirdId, secondId],
        };

        const action = actionCreators.changePointOrder({ oldIndex, newIndex });
        const actualState = pointsReducer(initialState, action);

        expect(actualState).toEqual(expectedState);
      });
    });

当我在on POINT_ORDER_CHANGE action block 中将initialState值记录到控制台时,它给了我没有第一个元素的initialState值,就好像它一样在 POINT_REMOVE reducer 内部进行了修改。

我做错了什么? 谢谢!

最佳答案

我相信您的问题可能与此行有关:

    const newState = { ...state }

newState 确实是 state 的副本,但它不会是深拷贝。这意味着嵌套在 state 对象中的对象将通过引用复制,而不是将值重新创建为新对象。也就是说,您正在修改原始的 byIdid 对象。这样,原来的对象就会被更新。如果您不希望发生这种情况,则需要深度克隆状态对象,或者复制 byIdid 并将突变应用于这些对象,而不是复制它们原始对象。

例如: 复制 byIdid(个人首选方法)

  const newState = { ...state }
    const { byId, ids } = newState;
    const { id } = action;
    const copyById = { ...byId };
    const copyIds = [...ids];

状态的深度克隆:

const newState = JSON.parse(JSON.stringify(state));

关于javascript - 对象无法正确复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57972223/

相关文章:

javascript - Javascript 中的类方法

javascript - 如何判断div之间是什么?

Javascript 函数只能暂时工作

javascript - 如何检查http post调用后函数是否被调用?

javascript - Rails 5 Redux React 服务器端渲染给出客户端 JavaScript 警告 'Replacing React-rendered children with a new...'

javascript - Using Redux.createStore with Immutable 抛出“reducer is not a function”(How to use Redux with Immutable.js ans composeEnhancers)

redux - 用户变量值作为类型

javascript - 是否可以修改 Google Charts 折线图,以便无论光标位于图表上的哪个位置都显示点?

javascript - Redux Action 创建者在另一个内部调用一个

reactjs - 如何为具有自己状态的多个 React 组件重用相同的 Redux Saga?