Реакция Redux, я тут мутирую? - PullRequest
0 голосов
/ 06 ноября 2018

Я играю с простым приложением 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 голосов
/ 06 ноября 2018

Вы правы в своем предположении. Во втором примере вы изменяете состояние, и это не вызывает повторную визуализацию. Вы никогда не должны мутировать состояние. Всегда делайте копию состояния и возвращайте новое состояние.

0 голосов
/ 06 ноября 2018

Если вы извлечете Redux doc , вы обнаружите, что они предлагают использовать либо Object.assign () , либо Синтаксис распространения объекта , чтобы предотвратить изменение состояния.

Оба решения жизнеспособны.

С другой стороны, рекомендуется использовать операторы 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
  }
}
0 голосов
/ 06 ноября 2018

Да, вы изменяете исходное состояние, а не возвращаете новый объект состояния с увеличенным счетчиком.

Вы могли бы сделать это (не большой смысл в этом случае, но показывает проблему)

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 
}

Таким образом, это новый объект, поэтому старые объекты состояния остаются неизменными

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...