使用 redux-thunk 中间件在 redux 中更正异步操作类型

Correct type of async action in redux with redux-thunk middleware

我在学习中间件redux-thunk的过程中创建了一个简单的react App。由于接口 PostListProps 中的异步操作 fetchPosts 类型不正确,我遇到了转译问题。

下面我展示了功能组件的所有代码哪里出了问题:

import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import { fetchPosts } from '../actions'
import Action from '../actions/actionTypes'
import { Dispatch } from "react";
import State from '../reducers/State'

interface PostListProps { 
    fetchPosts: () => (dispatch: Dispatch<Action>) => Promise<void>
}

const PostList = (props: PostListProps) => {
    useEffect(() => {
        props.fetchPosts()
    }, [])
    return (
        <div>Post List</div>
    )
}

const mapStateToProps = (state: State) => {
    return { posts: state.posts };
};

export default connect(
    mapStateToProps,
    { fetchPosts }
)(PostList);

只有当我将 fetchPosts 函数的类型更改为:

fetchPosts: () => any

下面我给出函数fetchPosts的代码:

import Action, { ActionType } from "./actionTypes";
import jsonPlaceholder from "../apis/jsonPlaceholder";
import { Dispatch } from "react";
import Post from '../apis/Post'
import State from "../reducers/State";
import { AxiosResponse } from "axios";

export const fetchPosts = () => {
    return async (dispatch: Dispatch<Action>) => {
        const response: AxiosResponse<Post[]> = await jsonPlaceholder.get<Post[]>('/posts')
        dispatch({type: ActionType.FETCH_POSTS, payload: response.data });
    }
}

错误如下:

我不知道哪里会出问题?为什么我的 fetchPosts() 类型是错误的?我想知道。 我将不胜感激。

您的组件不关心如何获取帖子并将其发送到商店的细节,因此 dispatch 位不需要反映在界面中。所有需要的接线都由 react-redux.

处理

试试这个:

interface PostListProps {
    fetchPosts: () => void;
}

请注意,界面中未提及 Promise,因为您的组件并不等待它。

至于如何正确键入 dispatch 函数,我们可以从 store 实例中推断出正确的类型:

import thunk, { ThunkMiddleware } from 'redux-thunk';

interface AppState {
    posts: PostsState;
    claims: ClaimsState;
}

type AppAction = PostsAction | ClaimsAction;

type AppThunk = ThunkMiddleware<AppState, AppAction>;

const reducer: Reducer<AppState, AppAction> = combineReducers({
  posts: postsReducer,
  claims: claimsReducer,
});

const store = createStore(
    reducer,
    applyMiddleware(thunk as AppThunk)
);

// the type is inferred as
// Dispatch<AppAction> & ThunkDispatch<AppState, undefined, AppAction>
type AppDispatch = typeof store.dispatch;

切片特定的状态和动作类型将在相应的切片中定义,如下所示:

// posts slice
export type PostsState = Post[];
export type PostsAction =
    | FetchPostsAction
    | FetchPostsFulfilledAction
    | FetchPostsRejectedAction;

// claims slice
export type ClaimsState = Claim[];
export type ClaimsAction =
    | CreateClaimsAction;

您可能还想看看 redux-toolkit 包,其中大部分内容都已得到处理。