将 const/function 移入自定义钩子/可重用代码段

Posted

技术标签:

【中文标题】将 const/function 移入自定义钩子/可重用代码段【英文标题】:Move a const/function in to a custom hook / re-usable piece of code 【发布时间】:2022-01-11 05:35:15 【问题描述】:

在我的功能组件/页面中,我有一个常量/函数,我将错误消息传递给它,然后更新几个 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);
;

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

编译失败

src/hooks/catchError.tsx Line 3:33: React Hook "useState" 不能 在顶层调用。必须在 React 中调用 React Hooks 函数组件或自定义 React Hook 函数 react-hooks/rules-of-hooks 第 4:33 行:React Hook "useState" 不能 在顶层被调用。必须在 React 中调用 React Hooks 函数组件或自定义 React Hook 函数 反应钩子/钩子规则

搜索关键字以了解有关每个错误的更多信息。

这对我来说是一个新领域,所以我一直在努力寻找解决方案,并感谢您为解决问题提供的任何意见。

谢谢。

(P.s. 我对反应/打字很陌生,如果我的术语有误,我深表歉意。我欢迎在这方面进行任何更正。)

【问题讨论】:

文件名catchError.tsx 和函数名应以use 为前缀,就像useCatchError 一样,以便react 将其识别为自定义钩子。此外,您必须在函数内移动您的 useStates 【参考方案1】:

如果您想重用钩子逻辑(如 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

【讨论】:

谢谢。我不想返回任何东西,我只需要传入 2 个值(e 和 message)。然后通过导入从任何其他页面/组件使用catchError。如果我根据您的代码导入 useCatchError 并导入为 import catchError from '../hooks/useCatchError'; 我收到错误 Module '"../hooks/useCatchError"' has no exported member 'catchError'. 有什么建议吗? 附言。我的 catchError 代码就是我在问题中发布的内容。我只需要能够跨多个组件/页面重用该代码,而无需在每个页面上手动完整地添加该代码。谢谢。 如果您不想返回消息和加载值,您可以将return catchError, message, loading ; 替换为return catchError,然后您将能够使用const catchError = useCatchError(); 获得该功能。但是你必须在你的渲染方法中为每个组件调用钩子,这是没有办法解决的。

以上是关于将 const/function 移入自定义钩子/可重用代码段的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将其转换为自定义的 React 钩子?

git自定义项目钩子和全局钩子

如何检测手指移入或移出我的自定义 UIView

在自定义钩子中访问 Redux 状态?

如何将 React 组件的自定义钩子与“map”一起使用

如何使用自定义钩子访问织物对象以将背景图像添加到画布?