首页 > 解决方案 > useEffect 清理函数 Typescript 错误:不可分配给“EffectCallback”类型的参数

问题描述

我有这段代码应该执行以下操作:

由于dispatch并且slug在此组件生命周期中不会发生变化,因此清理基本上将在组件卸载后运行。

const dispatch = useDispatch();
const slug = props.match.params.slug || "";

useEffect(() => {
  dispatch(THUNKS.LOAD_DATA(slug));
  return () => { dispatch(ACTIONS.RESET_STATE()); };
},[dispatch,slug]);

一切都按预期工作。但我想将清理函数编写为:

return () => dispatch(ACTIONS.RESET_STATE());

我知道return当我这样写时,箭头函数会添加一个隐式语句。所以基本上我正在回dispatch()电话。

正因为如此,Typescript 抱怨以下错误消息:

Argument of type '() => () => { payload: undefined; type: string; }' is not assignable to parameter of type 'EffectCallback'.

我认为正在发生的事情:EffectCallback可能期待void作为return,突然我正在回dispatch()电话。

我可以自定义类型以EffectCallback某种方式接受此返回调用并摆脱此错误吗?

标签: reactjstypescriptuse-effect

解决方案


问题dispatch实际上是返回动作对象,所以它不是一个void函数。您只想忽略返回的值。

我有一个可能看起来很愚蠢的解决方案,除非这是您经常使用的模式,因为我们所做的只是将花括号移到另一个地方。但它可能是一个地方而不是多个地方。

我们可以用我们自己的自定义版本覆盖,而不是弄乱打字稿定义,useDispatch实际上它不会返回任何东西。

import { useDispatch as useRegularDispatch } from "react-redux";
import { Action, AnyAction } from "redux";

export interface VoidDispatch<A extends Action = AnyAction> {
  <T extends A>(action: T): void;
}

export const useDispatch = <A extends Action = AnyAction>(): VoidDispatch<A> => {
  const regularDispatch = useRegularDispatch();

  return (action: A) => { regularDispatch(action); };
};

然后,您可以毫无问题dispatch地在清理中使用。useEffect


推荐阅读