React Redux,我在这里改变状态吗?

时间:2018-11-05 22:11:32

标签: javascript reactjs redux

我正在玩一个简单的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>
    )
  }
}

3 个答案:

答案 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
  }
}