Пользовательская стабильная функция диспетчера, использующая реагирующие хуки + useReducer - PullRequest
0 голосов
/ 02 апреля 2020

Итак, я пытаюсь создать функцию , которая будет отправлять действия редуктору. Вариант использования: я хочу отделить действия от API до актуальных обновлений состояния приложения. Создание слоя абстракции над функцией dispatch() из useReducer.

Я должен избежать повторного создания моей пользовательской функции диспетчера при изменении текущего состояния. Чтобы избежать запуска useEffect по всему приложению, просто потому, что мой useGlobalDispatcher был перегенерирован из-за изменения состояния.

Подходит ли приведенный ниже метод для создания моей собственной функции диспетчера?

Я использую useRef для установки предыдущего состояния, чтобы функция диспетчера не зависела от реального обновленного состояния.

useGlobalState.ts

import { useReducer, Dispatch, useRef, useEffect } from "react";
import reducer, { initialState, IState, IAction } from "../reducer";
import useSystemDispatcher from "./useSystemDispatcher";

const useGlobalState = () => {
  const [state, dispatch] = useReducer(reducer, {
    ...initialState
  });
  const prevState = useRef<IState>(initialState);

  useEffect(() => {
    prevState.current = state;
  });
  const globalDispatcher = useGlobalDispatcher(dispatch, prevState);

  return { data: state, dispatch: globalDispatcher };
};

export default useGlobalState;

useGlobalDispatcher.ts

const useGlobalDispatcher = (dispatch: Dispatch<IAction>, prevState: RefObject<IState>) => {
  const dispatcher: (action: IApiAction | IAction) => void = useCallback(
    ({ type, payload }) => {
      if (!prevState.current) {
        console.error("prevState was null. Should not happen. Forgot initial state?");
        return;
      }
      switch(type) {
        case "ApiAddOne:
          dispatch({ type: "SetCounter", prevState.current.counter + 1 });
          break;
        case "ApiSendState:
          dispatch({ type: "State", payload });
          break;
      }
    },
    [dispatch, prevState]
  );

  return dispatcher;
};

export default useGlobalDispatcher;

Насколько я понимаю, useGlobalDispatcher теперь должен быть "стабильным", так как он полагается:

  • на "рассылку" (которая по умолчанию стабильна)
  • и «prevState», который является ссылкой, который также стабилен.

Является ли это приемлемым методом добавления еще одного уровня функции для действий диспетчеризации?

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