• React报错之Invalid hook call


    正文从这开始~

    总览

    导致"Invalid hook call. Hooks can only be called inside the body of a function component"错误的有多种原因:

    1. reactreact-dom的版本不匹配。
    2. 在一个项目中有多个react包版本。
    3. 试图将一个组件作为一个函数来调用,例如,App()而不是
    4. 在类里面使用钩子,或者在不是组件或自定义钩子的函数中使用钩子。

    invalid-hook-call-hooks-can-only-be-called.png

    版本匹配

    在项目的根目录下打开终端,更新reactreact-dom包的版本,确保版本是相匹配的,并且没有使用过时的版本。

    # 👇️ with NPM
    npm install react@latest react-dom@latest
    
    # 👇️ ONLY If you use TypeScript
    npm install --save-dev @types/react@latest @types/react-dom@latest
    
    # ----------------------------------------------
    
    # 👇️ with YARN
    yarn add react@latest react-dom@latest
    
    # 👇️ ONLY If you use TypeScript
    yarn add @types/react@latest @types/react-dom@latest --dev
    

    如果错误仍存在,尝试删除node_modules以及package-lock.json(不是package.json)文件,重新运行npm install 并重启你的IDE。

    这个错误通常是由于在同一个项目中拥有多个版本的react造成的。

    # 👇️ delete node_modules and package-lock.json
    rm -rf node_modules
    rm -f package-lock.json
    
    # 👇️ clean npm cache
    npm cache clean --force
    
    npm install
    

    如果错误仍然存在,请确保重启了IDE和开发服务。VSCode经常出现故障,需要重启。

    调用组件

    这里有另一个示例,用来展示错误是如何发生的。

    // App.js
    import {useState} from 'react';
    
    // 👇️ Don't call components as functions 👇️
    App();
    
    export default function App() {
      /**
       * ⛔️ Warning: Invalid hook call. Hooks can only be
       * called inside of the body of a function component.
       *  This could happen for one of the following reasons:
    1. You might have mismatching versions of React and the renderer (such as React DOM)
    2. You might be breaking the Rules of Hooks
    3. You might have more than one copy of React in the same app
       */
      const [count, setCount] = useState(0);
    
      return (
        <div>
          <h1>Hello worldh1>
        div>
      );
    }
    

    问题在于,我们将App组件作为函数进行调用。

    你应该只使用具有JSX语法的组件。比如:,而不是App({country: 'Austria', age: 30})

    确保你没有在一个类组件,或一个既不是组件也不是自定义钩子的函数里面调用钩子。

    如果你有一个类,请将其转换为能够使用钩子的函数。

    下面是一个例子,说明在一个既不是组件也不是自定义钩子的函数中是如何引起错误的。

    // App.js
    import {useState, useEffect} from 'react';
    
    // 👇️ not a component nor custom hook
    // so it can't use hooks
    function counter() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        console.log('hello world');
      }, []);
    }
    

    counter函数以小写的c开头,所以它不被React认为是一个组件。因为所有的组件名称必须以大写字母开头。它同样也不是自定义钩子,因为其名称没有以use开头,比如说useCounter

    我们只能在函数组件或自定义钩子里面使用钩子,所以能够使用钩子的一个方法是将counter重命名为useCounter

    import {useState, useEffect} from 'react';
    
    function useCounter() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        console.log('hello world');
      }, []);
    }
    

    现在React认为useCounter是一个自定义钩子,并允许我们在里面使用钩子。

    就像文档中所说的那样:

    • 只从React函数组件或自定义钩子中调用Hook
    • 只在最顶层使用 Hook
    • 不要在循环,条件或嵌套函数中调用 Hook
    • 确保总是在你的 React 函数的最顶层以及任何 return 之前使用 Hook
  • 相关阅读:
    阿里的24W字Java面试复盘指南,GitHub已标星80k
    采用PHP开发的一套(项目源码)医疗安全(不良)事件报告系统源码:统计分析,持续整改,完成闭环管理
    非科班,补基础
    嵌入式系统开发笔记89:认识AVR微控制器系统架构
    八股文第十八天
    C语言perror
    人工智能第2版学习——盲目搜索1
    【Python】Python 格式化文本转换
    众焱公司网络平台建设-传输网的规划与设计
    supOS APP开发者课程练习册
  • 原文地址:https://www.cnblogs.com/chuckQu/p/16622367.html