javascript - Hur man använder Redux 4.0 TypeScript-bindningar med redux-thunk
Jag har problem med att använda de nya TS-bindningarna för Redux 4.0 med redux-thunk. Jag har återskapat problemet genom att konvertera det grundläggande Redux "Todo List"-exemplet till TypeScript (repo här) och göra Add Todo-åtgärden till ett thunk. Problemet är detsamma som rapporterat här: Argument of type 'ThunkAction' is not assignable to parameter of type 'AnyAction'. Property 'type' is missing in type 'ThunkAction'.
I princip kan jag få det att fungera, men jag använder any på ett par ställen där jag inte tror att jag borde. Ett ställe är index.tsx#L14, där jag lägger till thunk-middleware i butiken:
const store = createStore(
rootReducer,
applyMiddleware(thunk as ThunkMiddleware<IRootState, any>)
);
Om jag använder något annat än any där, kastar nästa rad felet:
store.dispatch(addTodo('Use redux-thunk'));
Den andra platsen är AddTodo.tsx#L7, där jag deklarerar dispatch-propen som injiceras av connect-funktionen:
interface IAddTodoProps {
dispatch: Dispatch<any>;
}
const AddTodo = ({ dispatch }: IAddTodoProps) => {
...
}
export default connect()(AddTodo);
På båda ställena åsidosätter any en typ som måste utvidga Action<any>. Action kräver ett type-attribut, vilket en thunk naturligtvis inte har. Hur kan jag deklarera dessa typer så att dispatch-funktionen accepterar en thunk?
Relaterad fråga
Relevant PR
Svar #1
diff --git a/src/containers/AddTodo.tsx b/src/containers/AddTodo.tsx
index e49ac4a..20a93d6 100644
--- a/src/containers/AddTodo.tsx
+++ b/src/containers/AddTodo.tsx
@@ -1,10 +1,12 @@
import * as React from 'react';
import { connect } from 'react-redux';
-import { Dispatch } from 'redux';
+import { ThunkDispatch } from 'redux-thunk';
+import { AnyAction } from 'redux';
import { addTodo } from '../actions';
+import { IRootState } from '../reducers/index';
interface IAddTodoProps {
- dispatch: Dispatch<any>;
+ dispatch: ThunkDispatch<IRootState,any,AnyAction>;
}
const AddTodo = ({ dispatch }: IAddTodoProps) => {
Svar #2
Svaret på denna fråga (och många andra) visade sig vara: använd Redux Toolkit.
Butiksuppsättningen är busenkel:
// src/redux/store.ts
import { configureStore } from '@reduxjs/toolkit';
import reducer from './reducers';
const store = configureStore({ reducer });
export type AppDispatch = typeof store.dispatch;
export default store;
Sedan, när du använder useDispatch-hooken från react-redux, skriv den bara som AppDispatch:
// src/components/App.tsx
import { useDispatch } from 'react-redux';
import { AppDispatch } from '../redux/store';
const App = () => {
const dispatch: AppDispatch = useDispatch();
// ...
}
