React.js/Redux: setInterval и clearInterval в редьюсерах

В настоящее время я работаю над игрой FCC Life, и мне удалось выяснить, как сгенерировать следующее состояние приложения (поэтапно).

При этом мой следующий шаг — выяснить, как непрерывно генерировать новое состояние приложения (поколение). В этом случае я пытаюсь реализовать setInterval и clearInterval внутри моего редьюсера.

Я хотел бы иметь возможность запускать/приостанавливать создание нового поколения (путем переключения состояния в state.start)

Проблема, с которой у меня возникают проблемы при реализации, - это проблема области действия.

Вот часть моего редуктора:

редукторы/reducers_grid.js

export default function(state = initialState, action){
  switch (action.type) {
    ....
    case START:
      let toggleStart = state.start === true ? false : true;

      if (state.start === true){
        console.log('START THE GAME')

        const newGeneration = nextGeneration(action.payload,state)
        return Object.assign({}, state, {cells: newGeneration, start: toggleStart })
      }
      else {
        console.log('PAUSE THE GAME')
        return Object.assign({}, state, {start: toggleStart })
      }

  return state;
}

По сути, функция nextGeneration возвращает новое состояние приложения (поколение) и обновляет его через Object.assign

Сначала я думал поместить setInteveral в первый оператор if и clearInterval во второй оператор if, но, очевидно, это создаст проблему с областью действия.

Эта часть логики кажется очень тривиальной, но я застрял на этом некоторое время.


person Alejandro    schedule 18.09.2016    source источник


Ответы (1)


Не делайте этого в редукторе. Редюсеры должны быть чистыми функциями (то есть без побочных эффектов). Вместо этого вы можете создать компонент, который отображается только во время работы игры (логическое состояние, которое устанавливается в true действием START и в false действием STOP). Затем в функции componentDidMount компонента вызовите setInterval с функцией, которая отправляет действие NEXT_GENERATION. После этого отправьте еще одно действие, которое добавит идентификатор таймера в хранилище. Затем в componentWillUnmount вызовите clearInterval с идентификатором таймера.

person Jack Noble    schedule 19.09.2016