объединить редукторы для реагирующих хуков и контекста с типобезопасным - PullRequest
0 голосов
/ 25 апреля 2020

Так что я пытаюсь использовать реакционные хуки и контекстные 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

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