React Hook之钩子调用规则(不在循环、条件判断或者嵌套函数中调用)

React Hook之钩子调用规则(不在循环、条件判断或者嵌套函数中调用)

hooks使用规则

  • 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
  • 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。(还有一个地方可以调用 Hook —— 就是自定义的 Hook 中)

错误使用案例

代码:

  const useCustomItemRender = (originNode: React.ReactNode, file: CustomUploadFile) => {
   
    const [editing, setEditing] = useState(false);
    const [newName, setNewName] = useState(file.name);
  
    const handleEdit = () => {
   
      setEditing(true);
    };
  
    const handleSave = () => {
   
      setEditing(false);
      handleEditDescription(file.uid, newName);
    };
  
    const render = editing ? (
      <div>
        <Input
          value={
   newName}
          onChange={
   (e) => setNewName(e.target.value)}
          onPressEnter={
   handleSave}
          onBlur={
   handleSave}
          autoFocus
        />
      </div>
    ) : (
      <div onClick={
   handleEdit}>{
   file.name}</div>
    );
  
    return render;
  };
  
  const customItemRender: ItemRender<CustomUploadFile> = (originNode, file) => {
   
    const render = useCustomItemRender(originNode, file);
    return render;
  };

报错:
React Hook “useCustomItemRender” is called in function “customItemRender: ItemRender” that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word “use”.

报错解释:
这个错误表明你在React函数组件中使用了名为useCustomItemRender的自定义钩子(Hook),而这个钩子的使用发生在一个内嵌函数customItemRender中。React的钩子(Hooks)只能在函数组件的主体或者其他钩子中调用,而不能在嵌套函数或者控制流逻辑中调用。这个规则被称为“钩子调用规则”。

解决方法:
确保useCustomItemRender只在组件的主体中调用一次。如果customItemRender是一个独立的函数,你应该将useCustomItemRender的调用移到customItemRender函数外部,确保它不会在customItemRender内部被调用。如果customItemRender是一个React组件,那么应该将useCustomItemRender的调用保持在该组件的主体中。

// 不正确的使用方式
function MyComponent() {
   
  function customItemRender() {
   
    const [value, setValue] = useCustomItemRender(); // 错误,在内嵌函数中调用钩子
    // ...
  }
  // ...
}

// 正确的使用方式
function MyComponent() {
   
  const [value, setValue] = useCustomItemRender(); // 正确,在组件主体中调用钩子

  function customItemRender() {
   
    // 使用value和setValue
    // ...
  }
  // ...
}

如果useCustomItemRender是一个自定义的钩子,它应该遵循React的钩子调用规则,即不在循环、条件判断或者嵌套函数中调用。如果需要在多个地方复用状态逻辑,可以考虑使用自定义组件或高阶组件。

总结:在内嵌函数 customItemRender 中调用了自定义的钩子 useCustomItemRender,而 React 钩子(Hooks)只能在函数组件的主体或其他钩子中调用,不能在嵌套函数中调用。

案例具体解决方法

为了解决这个问题,我们需要将 customItemRender 函数转换为一个自定义的 React 组件,以便在组件主体中调用钩子。

  const CustomItemRender: React.FC<{
    originNode: React.ReactNode, file: CustomUploadFile }> = ({
     originNode, file }) => {
   
    const render = useCustomItemRender(originNode, file);
    return render;
  };

  const customItemRender: ItemRender<CustomUploadFile> = (originNode, file) => {
   
    const render = <CustomItemRender originNode={
   originNode} file={
   file} />;
    return render;
  };

这段代码定义了一个名为 CustomItemRender 的组件,并将其用作 customItemRender 函数的返回值。

通过将 customItemRender 函数转换为一个自定义的 React 组件 CustomItemRender,我们可以在组件主体中调用钩子。

相关推荐

  1. 条款09:绝析构和构造调用virtual函数

    2024-02-05 07:32:03       20 阅读
  2. 如何Go定义和调用函数

    2024-02-05 07:32:03       46 阅读
  3. Lua 如何Lua调用C/C++函数

    2024-02-05 07:32:03       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-05 07:32:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-05 07:32:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-05 07:32:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-05 07:32:03       18 阅读

热门阅读

  1. 如何接手一个新系统

    2024-02-05 07:32:03       30 阅读
  2. 【npm】npm install 卡住不动

    2024-02-05 07:32:03       27 阅读
  3. Tomcat环境搭建

    2024-02-05 07:32:03       27 阅读
  4. Vue3中ref与reactive的用法详解——reactive

    2024-02-05 07:32:03       30 阅读
  5. 在建站和小程序方面,公司如何提升客户的体验

    2024-02-05 07:32:03       32 阅读