Вступление
Я использую Redux Toolkit, чтобы добавить поддержку Redux в приложение React, обслуживаемое приложением Django. Мы используем Typescript, поэтому следуем Краткому началу работы с Typescript из Документы Redux Toolkit.
Важным элементом использования Redux (Toolkit?) С Typescript является обеспечение того, чтобы ваш dispatch(...)
метод имел правильную сигнатуру типа. Как описано в документации, если вы просто используете useDispatch(...)
крючок от react-redux,
тип
Dispatch
по умолчанию не знает о преобразователях. Чтобы правильно отправлять преобразователи, вам необходимо использовать определенный настроенный типAppDispatch
из магазина, который включает типы промежуточного программного обеспечения преобразователей, и использовать его сuseDispatch
. Добавление предварительно набранногоuseDispatch
хука убережет вас от того, чтобы забыть импортироватьAppDispatch
туда, где это необходимо.
Это нормально, и я выполнил эти инструкции. Мой код экспортирует новый хук, как и в учебнике:
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
Моя проблема: когда я использую этот перехватчик, подпись типа для метода dispatch(...)
по-прежнему не принимает переходы. Следующий код:
const dispatch = useAppDispatch();
dispatch(customAction({ ... params ... }));
Выдает ошибку компиляции:
ERROR in [at-loader] ./src/components/Widget.tsx:45:9
TS2345: Argument of type 'AsyncThunkAction<void, CustomActionParams, {}>' is not assignable to parameter of type 'AnyAction'.
Property 'type' is missing in type 'AsyncThunkAction<void, CustomActionParams, {}>' but required in type 'AnyAction'.
Мой вопрос: Почему типизированный метод отправки неправильно принимает AsyncThunkAction
s?
Вещи, которые я пробовал
Интересно, что вызов dispatch(...)
с явно параметризованным типом AppDispatch
приводит к той же ошибке. Только параметризация dispatch(...)
с any
заглушает ошибку, что, очевидно, не идеально.
const dispatch = useAppDispatch();
dispatch<AppDispatch>(customAction({ ... params ... })); // same error
dispatch<any>(customAction({ ... params ... })); // error silenced
Это заставляет меня думать, что проблема в AppDispatch
неправильном выводе о том, что он должен принимать AsyncThunkAction
типы, что должно происходить автоматически. Причиной этого может быть то, что мое асинхронное действие определено в пределах extraReducers
, вот так:
export const customAction = createAsyncThunk(
"slice/customAction",
async (payload: CustomActionParams) { ... }
);
export const slice = createSlice({
name: "slice",
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(customAction.fulfilled, (state, action) => { ... });
}
});
Я не уверен, почему это не приведет к обновлению типа, но это то, что я должен решить.
Отличия от стандартной настройки
Некоторые аспекты моей среды также теоретически могут способствовать возникновению этой проблемы, поэтому я включаю их сюда для правильности:
- This React application is not a single page application, but is embedded in a rendered Django template by using django-react-templatetags. This library automatically injects script tags inline to pass component props and initialize components using
ReactDOM
. See this page for an example on how this works.- This means that each component has its own
<Provider>
component, instead of one<Provider>
at the root, but all share the same store.
- This means that each component has its own
- Пользовательский метод
useAppDispatch(...)
определен в моем файле магазина (store.ts
), а неhooks.ts
в корне, но это не должно вызывать никаких проблем. - Изменить: все это находится в Yarn 2 Workspace, а не в корневой каталог пакета.
Вопросы, которые не повторяются:
- В этом вопросе используется неправильное определение для
useAppDispatch(...)
. Я использую правильное определение в своем коде. - В этом вопросе не используется настраиваемый обработчик отправки.
- В этом вопросе используются неправильные и чрезмерно определенные типы для
dispatch
метода объектаthunkAPI
в _ 31_ методcreateAsyncThunk
, который я в настоящее время не использую. Я пытаюсь использоватьdispatch
как импортированный через ловушку в компоненте, а не в моемpayloadCreator
методе.