setInterval, модифицирующий глобальное состояние - PullRequest
1 голос
/ 29 марта 2020

Я новичок в Javascrit и Redux. Я просмотрел несколько ссылок и наткнулся на эту статью о промежуточном программном обеспечении в Redux: https://www.codementor.io/@vkarpov / beginner-s-guide-to-redux-middleware-du107uyud

Автор заявил, что редукторы не должны изменять глобальное состояние (таким образом, чистую функцию), поэтому редукторы не должны использовать функции вроде setInterval.

Если я правильно понимаю, это означает, что setInterval действительно изменяет глобальное состояние. Мой вопрос был бы о том, как и какую часть глобального состояния setInterval изменяет?

Буду признателен за любые подробности.

Спасибо.

1 Ответ

0 голосов
/ 29 марта 2020

Редукторы не должны отвечать за управление асинхронными c действиями. setInterval не изменяет глобальное состояние по своей сути, но если оно вызывается изнутри редуктора, оно имеет потенциал для доступа и изменения состояния через ссылки на объекты.

Цель этого правила - сохранить ваш код чистым, сфокусированным и просто. Как таковые редукторы должны принимать состояние и действие и генерировать новое состояние синхронно. Никаких других махинаций.

Вот почему существуют Redux Thunk и Redux Sagas. Они дают нам возможность обрабатывать многие фазы асинхронных действий c, сохраняя логику c вне редукторов.

Например, представьте следующий редуктор:

// Simple reducer that ignores action and just adds 1 to
// state count every time
function myReducer(state, action) {
    return {
        count: state.count + 1
    };
}

// Reducer that calls setInterval
function myBadReducer(state, action) {
    // When our reducer gets called we create an interval
    // that increases count directly by 1 every 2 seconds
    // BTW This is exceptionally bad since it creates a duplicate
    // interval everytime the reducer is invoked.
    setInterval(() => {
        state.count += 1;
    }, 2000);

    return state;
}

Плохой редуктор изменяет состояние напрямую через ссылки, которые нарушают созданный для нас редукционный поток. Состояние -> Действие -> Редуктор -> Новое состояние. Это делает невозможным для Redux оперативное уведомление всех подписчиков о том, что состояние изменилось, поскольку он не отслеживает каждый адрес памяти.

Вместо этого вам следует настроить отдельный процесс вне редуктора (или использовать Redux Sagas), который вызывает действовать по мере необходимости (с интервалом или как-то иначе), и пусть хранилище обрабатывает вызов редуктора и каждый раз генерирует новое состояние.

...