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();
  // ...
}

Relaterade artiklar