Итак, я пытаюсь создать функцию , которая будет отправлять действия редуктору. Вариант использования: я хочу отделить действия от 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», который является ссылкой, который также стабилен.
Является ли это приемлемым методом добавления еще одного уровня функции для действий диспетчеризации?