钩子只能在函数组件的主体内部调用。(fb.me/react-invalid-hook-call)

IT技术 javascript reactjs react-hooks react-functional-component
2021-03-25 05:52:02
import  { useEffect } from "react";

export const Routes = () => {
  useEffect(() => {
    console.log("red")
  }, []);

  const a = [{ name: "sathish" }];
  const b = [{ name: "pandi" }];
  const c = [{ name: "suren" }];
  if (false) {
    return a;
  } else {
    return b;
  }
};

使用此代码,我有错误,例如只能在函数组件的主体内调用 × Hooks。

在此处输入图片说明

2个回答

查看Hooks规则以了解它们的限制以及它们的用途。

不要在循环、条件或嵌套函数中调用 Hook。相反,始终在 React 函数的顶层使用 Hook。通过遵循此规则,您可以确保每次渲染组件时都以相同的顺序调用 Hook。

与其他答案和评论不同,导入 React 并返回 JSX并不是将函数视为组件的要求。

从概念上讲,组件就像 JavaScript 函数。它们接受任意输入(称为“props”)并返回描述应该出现在屏幕上的内容的 React 元素。

React 组件的最低要求:

  1. 返回一个 React元素1,它可以是任何可以渲染的元素:数字、字符串、其他元素或任何这些元素的数组。
    请注意,布尔值 和null被忽略。严格返回undefined(或不返回,这是相同的)将失败。

  2. 那么它必须用作组件:<MyComponent />React.createElement(MyComponent)在渲染阶段内使用。

您不是将其Routes用作 React 组件,而是在渲染阶段之外将其作为函数调用。

import Cookies from 'js-cookie';
import { Routes } from 'routes.js'
import { Redirect } from 'react-router-dom';
const routes = Routes(); // <-- Called as a function, not a component

这就是您收到错误的原因。

当您在函数useEffect内部的正确位置调用Routes,由于它不在 React 的渲染流程中调用,因此 React 正在检测它,就好像它在函数组件之外一样


话虽如此,由于您没有解释您要完成的工作,我们无法告诉您如何解决它。告诉您在另一个组件中使用Routes 可能会产生误导。


1. 虽然在 React 文档中被称为元素,但在处理prop-types它被称为节点

从技术上讲,您缺少 2 个重要步骤,import React零件和返回JSX.

您可以采取以下措施使其工作:

import React, { useEffect } from 'react';

export const Routes = () => {
  useEffect(() => {
    console.log("red")
  }, []);

  const a = [{ name: "sathish" }];
  const b = [{ name: "pandi" }];
  const c = [{ name: "suren" }];

  return a.map((e, i) => <span key={i}>{e.name}</span>);
};

此外,我添加了一个Array.prototype.map()来表示<span>元素中数组的名称对于代码示例,我删除了您的if声明。

更新:

同样基于评论,该问题与AdminRoutes组件外部调用代码中组件有关

您还需要做些什么才能使其包含到Admin组件render功能中,如下所示:

class Admin extends Component {
   // rest of your code

   render() {
      return <>
         {/* rest of the code */}

         <Routes />
      </>
   }
}

我希望这有帮助!

导入 React 并返回 JSX 不是这里的问题。OPRoutes以一种根本不用作组件的方式调用const routes = Routes()如图所示。否则,他不会收到错误,因为它被正确定义为组件。
2021-06-05 05:52:02
@EmileBergeron 完全正确,感谢您指出这一点,刚刚更正了答案,请再看一遍。
2021-06-10 05:52:02