将 const/function 移动到自定义挂钩/可重复使用的代码段

Move a const/function in to a custom hook / re-usable piece of code

在我的功能组件/页面中,我有一个 const/function,我将错误消息传递给它,然后更新几个 useState 记录并将错误记录到控制台。它看起来像这样:

const catchError = (e:any, message:string) => {
    //throw new Error(e)
    setMessage(message);
    setLoading(false);
    console.error(e);
};

我想将这段代码移动到一个挂钩 (?) / 帮助程序文件中,这样我就可以将它导入到任何其他组件中。这意味着我可以使用一段集中的代码,而不是在多个地方编写相同的代码,从而避免相关问题。

因此,我创建了一个包含以下内容的新 catchError.tsx 文件:

import { useState } from 'react';

const [ message, setMessage ] = useState("idle");
const [ loading, setLoading ] = useState(false);

export const catchError = (e:any, message:string) => {
    //throw new Error(e)
    setMessage(message);
    setLoading(false);
    console.error(e);
};

但是,当我渲染它时,出现以下编译错误:

Failed to compile

src/hooks/catchError.tsx Line 3:33: React Hook "useState" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks Line 4:33: React Hook "useState" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks

Search for the keywords to learn more about each error.

这对我来说是新领域。

(PS:我对 React / TypeScript 很陌生,欢迎对我的术语进行任何更正。

如果您想重用挂钩逻辑(如 useState),您可以编写自己的自定义挂钩。

我相信这样的东西可以工作,但我不完全确定在没有更多上下文的情况下如何使用它。

import { useState } from 'react';

function useCatchError() {
  const [ message, setMessage ] = useState("idle");
  const [ loading, setLoading ] = useState(false);

  const catchError = (e:any, message:string) => {
    //throw new Error(e)
    setMessage(message);
    setLoading(false);
    console.error(e);
  };

  return { catchError, message, loading };
}

并像

一样使用
export function Foo() {
  const {catchError, message, loading} = useCatchError();
  
  try {
    bar();
  } catch (e) {
    catchError(e, e.message);
  }

  return (
    <div>
       {message ? `Error: ${message}` : loading ? "Loading" : "Foo"}
    </div>
  );
}

有关 React 文档中自定义挂钩的更多信息:https://reactjs.org/docs/hooks-custom.html