React redux - 在状态树对象中向数组添加多个项目的问题

时间:2017-01-10 14:36:47

标签: reactjs redux react-redux

我正在寻找redux并为数组添加名称。下面的代码有效(有点!)。

我有几个问题。

  1. 我知道每次状态通过reducer时都建议创建一个新的状态树对象,但是我认为即使我更改了传入的状态对象它仍然可以工作。 在下面的代码中console.log(store.getState());如果我使用var newArr = state.names.concat(action.name);,则无效,但如果我使用state.names.push(action.name);

  2. 则无效
  3. 如果我添加了另一个store.dispatch(action),则代码无效。

    store.dispatch({type: 'ADD_NAME',name: 'PhantomTwo'});

  4. 任何人都可以解释为什么会这样吗?

    1. 最后,我是否需要在switch语句之外再次返回状态?
    2. 以下是我目前在下面的代码。

      const initialState = {
          names: []
      }
      
      function namesApp(state = initialState, action) {
          switch(action.type) {
              case 'ADD_NAME':
                  var newArr = state.names.concat(action.name);
                  return newArr;
              default: 
                  return state;
          }
      }
      
      let store = createStore(namesApp);
      
      store.dispatch({
          type: 'ADD_NAME',
          name: 'Phantom'
      });
      
      console.log(store.getState()); //returns `["Phantom"]`
      

2 个答案:

答案 0 :(得分:4)

这是array对象可变性的行为

由于React非常关心重新渲染的状态变化,所以我们需要注意可变性。

下面的代码解释了阵列的可变性。

let x = [];

let y = x;

console.log(x);
console.log(y);

y.push("First");

console.log(x);
console.log(y);

let z = [...x]; //creating new reference

console.log(z);

x.push("Second");

console.log(x); //updated
console.log(y); //updated
console.log(z); //not updated

因此,为了获得更好的功能,您的减速器就像

function namesApp(state = initialState, action) {
    switch(action.type) {
        case 'ADD_NAME':
            return {
                ...state, //optional, necessary if state have other data than names
                ...{
                   names: [...state.names, action.name]
                }
            };
        default: 
            return state;
    }
}

答案 1 :(得分:2)

[].concat返回一个新数组。但你的州是{ name: [] }。尽管使用新名称返回新构建对象,但上面的代码返回了新名称数组。

香草溶液

const initialState = { names: [] };

function namesApp(state = initialState, action) {
    switch(action.type) {
        case 'ADD_NAME':
            var newArr = state.names.concat(action.name);

            return {
                ...state,
                names: newArr
            };
        default: 
            return state;
    }
}

<强>不变性辅助

对于这类工作,我会使用immutability-helper

import u from 'immutability-helper'; 

function namesApp(state = initialState, action) {
    switch(action.type) {
        case 'ADD_NAME':    
            return u(state, {
                names: {
                    $push: action.name
                }
            });
        default: 
            return state;
    }
}

了解如何使用immutability-helper https://facebook.github.io/react/docs/update.html