首页 > 解决方案 > 在我的 React 应用程序中使用 redux dispatch 获取 TypeScript 错误

问题描述

React 新手,我正在尝试使用 Redux 实现 Flux,但是在使用异步操作调用 dispatch 时遇到 TypeScript 错误。

这是我的 App.tsx :

import React from 'react';
import { IonApp } from '@ionic/react';
import Main from './pages/Main';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './flux/reducers';
import { loginAttempt } from './flux/actions';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';

const loggerMiddleware = createLogger();

const store = createStore(rootReducer, 
  applyMiddleware(
    thunkMiddleware, loggerMiddleware
  )
);

let promise = store.dispatch(loginAttempt('test@host.org','test'));

promise.then(() => console.log(store.getState()));

class App extends React.Component {

  render() {

    return (
      <Provider store={store}>
        <IonApp>
          <Main/>
        </IonApp>
      </Provider>
  )}
}

export default App;

我的行动:

import fetch from 'cross-fetch';
import { Dispatch, Action } from 'redux';

export const LOGIN_REQUEST = 'LOGIN_REQUEST';
export const LOGIN_FAILURE = 'LOGIN_FAILURE';
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';

export function loginRequest() {
  return { type: LOGIN_REQUEST }
}

export function loginFailure(error: string) {
  return { type: LOGIN_FAILURE, error }
}

export function loginSuccess(sessionId: string) {
  return { type: LOGIN_SUCCESS, sessionId }
}

export async function loginAttempt(email: string, password: string) {

  return async function (dispatch: Dispatch<Action<any>>) {

    dispatch(loginRequest());

    return fetch("http://127.0.0.1:5000/login", {
      method: "post",
      headers: new Headers({
          "Content-Type": "application/json",
          Accept: "application/json",
      }),
      body: JSON.stringify({email, password})
      })
      .then(
        response => response.json()
      )
      .then(json =>
        dispatch(loginSuccess(json))
      )
  }
}

和减速器:

import { LOGIN_REQUEST, LOGIN_FAILURE, LOGIN_SUCCESS } from './actions';
import { combineReducers } from 'redux';

const initialState = {connected: false, sessionId: "", isFetching: false, failed: false, error:""};

function login(state = initialState, action: any) {
    switch (action.type) {
        case LOGIN_REQUEST:
            return Object.assign({}, state, {
                isFetching: true
            });

        case LOGIN_FAILURE:
            return Object.assign({}, state, {
                isFetching: false,
                failed: true,
                error: action.error
            });

        case LOGIN_SUCCESS:
            return Object.assign({}, state, {
                connected: true,
                isFetching: false,
                sessionId: action.sessionId
            });

        default:
            return state
    }
}

const rootReducer = combineReducers({
    login
})

export default rootReducer;

这会在编译时产生 TypeScript 错误:

Argument of type 'Promise<(dispatch: Dispatch<Action<any>>) => Promise<{ type: string; sessionId: string; }>>' is not assignable to parameter of type 'AnyAction'.
  Property 'type' is missing in type 'Promise<(dispatch: Dispatch<Action<any>>) => Promise<{ type: string; sessionId: string; }>>' but required in type 'AnyAction'.  TS2345

我敢肯定这是我的一些愚蠢行为,但我找不到我应该更改哪种类型才能使其正常工作。

知道我做错了什么吗?

标签: javascriptreactjstypescriptreduxreact-redux

解决方案


一位朋友最终帮我修复了它,我需要将中间件转换为 ThunkMiddleware :

const store = createStore(
  rootReducer, 
  applyMiddleware(
    thunkMiddleware as ThunkMiddleware<typeof initialState, Action<any>>
  )
);

从我的减速器导入的初始状态。

我的 loginAttempt 函数也已更改为不直接返回承诺:

export function loginAttempt(email: string, password: string) {
  return async function (dispatch: any) {
    [...]
  }
}

推荐阅读