【问题标题】:dispatch: Dispatch<AnyAction> why sometime you have to precise the Action?dispatch: Dispatch<AnyAction> 为什么有时你必须精确操作?
【发布时间】:2020-06-16 18:20:26
【问题描述】:

我遇到了一个问题,可能是因为我正在使用 typescript 尝试一些新的东西(输入 redux 的东西),

这是我的错误信息:Argument of type '(dispatch: Dispatch<AnyAction>) => Promise<string>' is not assignable to parameter of type 'AnyAction'. Property 'type' is missing in type '(dispatch: Dispatch<AnyAction>) => Promise<string>' but required in type 'AnyAction'. TS2345

这里的问题是我真的不明白为什么会出现这个错误,因为 typeScript 只是在这个上抛出错误,而不是在另一个上,所以我很困惑。

我的代码(有错误):

/Action/userAction.js
___________________________________________________
export const signOut = () => async (dispatch: Dispatch) => {
  try {
    dispatch(UserSignoutAction());
    dispatch(InitialErase());
    dispatch(signOutSessionInitial());
    dispatch(isLogout());
    persistor.flush();
    return "done";
  } catch (e) {
    const error = await e;
    throw error;
  }
};

/NavBar/container.js
_______________________________________________
const mapDispatchToProps = (
  dispatch: Dispatch
): {
  signOut: () => Promise<String>;
} => ({
  signOut: () => dispatch(signOut()),
});

这个例子抛出了一个错误,我可以用signOut: () =&gt; dispatch&lt;any&gt;(signOut()), 修复 我可以理解我需要输入调度好的(但不知道我需要什么,但目前这就是为什么我放一个任何)

其他代码(无错误):

/Action/userAction.js
___________________________________________________
export const sessionInitial = (
  session_id: number
): sessionInitialActionOption => ({
  type: SESSION,
  payload: session_id
});

/Dashboard/container.js
_______________________________________________
const mapDispatchToProps = (
  dispatch: Dispatch
): {
  sessionInitial: (
    session_id: number
  ) => {
    type: string;
    payload: number;
  };
} => ({
  sessionInitial: (session_id: number) => dispatch(sessionInitial(session_id))
});

我想我的错误是我想通过一个函数执行多个Actions Creator。我认为这不是这样做的好方法,或者这个解决方案还可以,但在 mapDispatchToProps 中放置/调用是荒谬的。

感谢您帮助我了解这部分的工作原理,它非常复杂。


_______________________________解决方案?____________________________


我找到了解决 Hassan Naqvi 提示的方法!以下代码对我有用:

const mapDispatchToProps = (
  dispatch: ThunkDispatch<
    void,
    void,
    | UserActionsType            //one of my actionsType
    | sessionActionsType         //one of my actionsType
    | isConnectActionsType       //one of my actionsType
    | initialUserActionsType     //one of my actionsType
  >
): {
  signOut: () => void;
} => ({
  signOut: () => dispatch(signOut())
});

type ApplicationDispatch = ThunkDispatch<IStoreState, void, AnyAction> & Dispatch

const mapDispatchToProps = (
  dispatch: ApplicationDispatch
): {
  signOut: () => void;
} => ({
  signOut: () => dispatch(signOut())
});

export default compose<any>(
  withRouter,
  connect(mapStateToProps, mapDispatchToProps)
);

我真的不明白为什么会这样,而不是上面的步骤......但我仍然会尝试理解为什么redux-thunk?以及为什么来自reduxDispatch 还不够(可能是因为actionsType 包含/发送函数ThunkDispatch)为什么不直接用actionsType 替换'any'signOut: () =&gt; dispatch&lt;any&gt;(signOut())? (不适合我)

DispatchThunkDispatch 有什么区别?

感谢大家阅读这篇文章,希望我能读到一些会改变我生活的文章!放纵的家伙。祝你有美好的一天!


-如上所见,当你使用redux-thunk处理异步动作时,动作到达最内层的函数actionFunction,它负责执行动作。但是这个 dispatch 是我们在中间件中创建的,它不是 createStore 的 dispatch,它有监听器并将值传递给 reducer。

-对reducer的调度发生在它的父函数nextFunction。

(来源:https://medium.com/@gethylgeorge/understanding-how-redux-thunk-works-72de3bdebc50

其他有用的链接:https://daveceddia.com/what-is-a-thunk/

所以如果我真的明白发生了什么,ThunkDispatch 能够执行 fct、异步 fct 或不执行 Dispatch。 Dispatch 正在调用 Actions Creator 到 reducer。

如果我错过了理解,请告诉我,我会纠正它。

希望对你有所帮助!

【问题讨论】:

    标签: reactjs typescript redux redux-thunk


    【解决方案1】:

    问题是,您在mapDispatchToProps 中使用Dispatch 类型作为您的第一个参数。

    由于您使用的是redux-thunk,因此您需要使用从redux-thunk 导入的ThunkDispatch 类型。

    所以你的 NavBar/container.ts 应该变成:

    import { AnyAction } from "redux";
    import { ThunkDispatch } from 'redux-thunk';
    
    // ApplicationState is the shape of your redux store.
    // You can use any but its recommended to have a specified shape
    // This should ideally be in a different file since it could be needed in many places
    interface ApplicationState {
       username: string;
       userId: string;
    }
    
    // Use ApplicationDispatch everywhere instead of Dispatch
    type ApplicationDispatch = ThunkDispatch<ApplicationState, void, AnyAction> & Dispatch
    
    const mapDispatchToProps = (
      dispatch: ApplicationDispatch
    ): {
      signOut: () => Promise<String>;
    } => ({
      signOut: () => dispatch(signOut()),
    });
    

    【讨论】:

    • 好的,但这是因为我在函数中使用了调度?当我更换我得到的所有东西时Generic type 'ThunkDispatch&lt;S, E, A&gt;' requires 3 type argument(s). TS2314我该怎么办?我不太明白你有一些文档或者你能给我解释一下吗?
    • 只是为了测试我做dispatch: ThunkDispatch&lt;any, any, any&gt;但得到了关注:Type '(dispatch: Dispatch&lt;AnyAction&gt;) =&gt; void' is missing the following properties from type 'Promise&lt;String&gt;': then, catch, [Symbol.toStringTag], finally TS2739
    • 好的,我找到了解决方案,谢谢您的提示!但我觉得我真的不明白...
    • 感谢您编辑了您的帖子,但我不明白 ApplicationState is the shape of your state. 是什么 StoreShape ?
    • 是的,就是这样。 redux 商店的形状。例如:您的 redux 状态可能包含类似:interface ApplicationState { username: string, password: string }。您可以在那里使用 ApplicationState 接口
    猜你喜欢
    • 2021-07-30
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多