Я дополняю функцию отправки контекста следующим образом:
const augmentDispatch = (
dispatch: React.Dispatch<Action | ApiAction>,
state: AppState,
) => (action: Thunk | Action | ApiAction) => {
if (typeof action === "object" && action.type === CALL_API) {
return callApi(action as ApiAction, dispatch);
}
return action instanceof Function
? action(dispatch, state)
: dispatch(action as Action);
};
Это позволяет мне вызывать вызов API для определенных действий. Затем я использую его так:
export function App(): JSX.Element {
const [state, dispatch] = useReducer(rootReducer, defaultState);
const augmentedDispatch = augmentDispatch(dispatch, state);
return (
<GlobalContext.Provider
value={{ state, dispatch: augmentedDispatch }}
>
Это прекрасно работает для обработчиков событий, но я столкнулся с бесконечным повторным рендерингом, когда попытался использовать его в useEffect
:
export const EditForm: React.FC = () => {
const { dispatch, state } = useContext(GlobalContext);
const dispatchLoadDetails = useCallback(
() => dispatch(loadDetails()),
[dispatch],
);
useEffect(() => {
dispatchLoadDetails();
}, [dispatchLoadDetails]);
return (
<Form
Кажется, я справился с этим, захватив ссылку на расширенную рассылку:
export function App(): JSX.Element {
const [state, dispatch] = useReducer(rootReducer, defaultState);
/**
* Note the usage of useRef here - without it we'd generate a new reference to
* augmentedDispatch with every call within useEffect, which would cause an
* indfinite re-render
*/
const augmentedDispatch = useRef(augmentDispatch(dispatch, state));
return (
<GlobalContext.Provider
value={{ state, dispatch: augmentedDispatch.current }}
>
Это лучший способ решить эту проблему? В документах указано, что useRef
следует использовать в качестве крайней меры ...