我正在玩一个简单的React Redux应用程序,该应用程序每次单击按钮都会增加一个计数器。我正在测试在Redux Reducer中增加计数器的两种不同方法。两种方法都可以改变减速器的状态,但是其中一种方法不会导致我的计数器重新呈现。
以下是缩小器,它将导致页面重新呈现:
const reducer = (state={speed: 0}, action) => {
if(action.type ==='INCREMENT_SPEED'){
state = {...state, speed: state.speed+=1
}
return state
}
这是起作用的代码,但不会导致页面以正确的值重新呈现。
const reducer = (state={speed: 0}, action) => {
if(action.type ==='INCREMENT_SPEED'){
state.speed++
}
return state
}
唯一的区别是我更新状态的方式。我的猜测是,使用++增量器实际上是在改变状态,这不会被视为更改,因此不会导致页面呈现。
如果有帮助,这是附加到DOM的代码的一部分:
render() {
return (
<div>
<p>SPEED: {this.props.reduxState.reducer.speed}</p>
</div>
)
}
}
答案 0 :(得分:5)
您的假设正确。在第二个示例中,您正在更改状态,并且不会触发重新渲染。您永远不要改变状态。始终复制状态并返回新状态。
答案 1 :(得分:4)
是的,您是在更改原始状态,而不是使用递增的计数器返回新的状态对象。
您可以那样做(在这种情况下,意义不大,但显示出了问题)
const reducer = (state={speed: 0}, action) => {
if (action.type ==='INCREMENT_SPEED'){
state = {...state} // copy the state to a new object
state.speed++; // increment the new object
return state; // return the new state object
}
那样,它是一个新对象,因此旧状态对象保持不变
答案 2 :(得分:2)
如果您结帐Redux doc,您会发现他们建议使用Object.assign()或Object spread syntax来防止状态变异。
这两种解决方案都是可行的。
顺便提一句,为简化器is encouraged使用switch语句。
使用Object.assign()
const reducer = (state={speed: 0}, action) => {
switch (action.type) {
case 'INCREMENT_SPEED':
return Object.assign({}, state, {
speed: state.speed + 1
})
default:
return state
}
}
使用对象传播语法
const reducer = (state={speed: 0}, action) => {
switch (action.type) {
case 'INCREMENT_SPEED':
return {...state, speed: state.speed + 1}
default:
return state
}
}