我正在寻找redux并为数组添加名称。下面的代码有效(有点!)。
我有几个问题。
我知道每次状态通过reducer时都建议创建一个新的状态树对象,但是我认为即使我更改了传入的状态对象它仍然可以工作。
在下面的代码中console.log(store.getState());
如果我使用var newArr = state.names.concat(action.name);
,则无效,但如果我使用state.names.push(action.name);
如果我添加了另一个store.dispatch(action)
,则代码无效。
store.dispatch({type: 'ADD_NAME',name: 'PhantomTwo'});
任何人都可以解释为什么会这样吗?
以下是我目前在下面的代码。
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"]`
答案 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