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

React redux - issues adding multiple items to an array in state tree object

我正在查看 redux 并将名称添加到数组。下面的代码有效(有点!)。

我有一些问题。

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

  2. ,则无效
  3. 如果我再添加一个 store.dispatch(action) 代码将不起作用。

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

谁能解释为什么会这样?

  1. 最后,我是否需要在 switch 语句之外再次 return 声明?

这是我目前拥有的代码。

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"]`

[].concat returns 一个新数组。但是你的状态是{ 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

这是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;
    }
}