Так что я пытаюсь использовать реакционные хуки и контекстные API для достижения провайдера, похожего на «избыточный». После прочтения множества публикаций и исследований по stackoverflow. Я смог заставить его работать, однако моя проблема в том, как объединить все редукторы для достижения «единого источника правды», и я хотел бы применить в нем типобезопасность. Я нашел эту функцию в stackoverflow, которая может объединять несколько редукторов в один, так что я могу использовать только 1 useReducer в моем ContextProvider:
const combineReducers = (reducers) => {
return (state, action) => {
const tempState = { ...state };
Object.keys(reducers).forEach((key) => {
tempState[key] = reducers[key](tempState[key], action);
});
return tempState;
};
};
Чтобы использовать приведенный выше код, просто передайте объект редукторов для аргумента redurs вот так:
const [state, dispatch] = useReducer(
combineReducers({
reducerA: ReducerA,
reducerB: ReducerB,
}),
INIT_STATE
);
однако это не разделяет озабоченность (по крайней мере, я так понимаю), как если бы вы взглянули на это:
const mainReducer = (state: InitialStateType, action: AppMenuActions | AuthActions | LayoutActions) => ({
appMenu: AppMenuReducer(state.appMenu, action),
auth: AuthReducer(state.auth, action),
layout: LayoutReducer(state.layout, action),
});
Это хорошо потому что теперь каждый редуктор получает только то состояние, которым управляет. Но я получаю ошибку типа с действием, потому что действие, которое было передано в mainReducer, является дискриминационным объединением, и действие для каждого из приемников - это только действия редуктора. Так что теперь, если я хочу, чтобы это работало, мне нужно было бы использовать различимые союзы всех действий всех моих редукторов в каждой функции редуктора. Это поражение цели разделения проблем.
Вы можете просмотреть весь код здесь: https://codesandbox.io/s/context-hooks-typescript-weh23?file= / src / context.tsx
у меня есть следующие вопросы: 1. если вы посмотрите на мой код в codeandbox, то увидите, что [состояние, диспетчеризация], который мы деструктурируем из useReduce, имеет тип any, однако, когда я передаю это значение провайдеру контекста, оно становится правильным типом. что из-за этого?:
type AppContextType = {
state: InitialStateType;
dispatch: React.Dispatch<AppMenuActions | AuthActions | LayoutActions>;
};
как мне сделать так, чтобы [state, dispatch] получил правильный тип? 2. Тип AppContextType выше, как мне улучшить его, потому что, если вы видите тип отправки, я использую различимые объединения, то хорошо, когда у меня есть 3 действия редуктора, но если это увеличение, оно выйдет из-под контроля. 3. Для функции mainReducer я могу исправить работоспособность кода, заставив действие всех моих редукторов предпринимать различимые объединения всех действий, и это нормально, но если у меня будет много других редукторов, это наверняка выйдет из-под контроля. Как мне сделать так, чтобы действие выводило тип на основе редуктора, который получает передачу. Я попытался преобразовать функцию conbineReducers, чтобы она была безопасной для типов, как эта, но она не полностью. Я борюсь, потому что я очень новичок, и мои знания ограничены:
const combineReducers = <S, A>(reducers: Array<Reducer<S, A>>) => {
return (state: S, action: A) => {
const tempState = { ...state };
Object.keys(reducers).forEach((key) => {
tempState[key] = reducers[key](tempState[key], action);
});
return tempState;
};
};
Я получаю ошибку в этой строке, и я не знаю, как ее исправить или где искать:
tempState[key] = reducers[key](tempState[key], action);
Спасибо, если вы прочитали это далеко, и тем, кто хочет взять свое время и помочь мне. Большое спасибо! источники: https://medium.com/hackernoon/finally-the-typescript-redux-hooks-events-blog-you-were-looking-for-c4663d823b01