React Hooks 错误:只能在函数组件内部调用 Hooks

IT技术 javascript reactjs react-hooks
2021-04-01 06:38:03

使用useState钩子时出现此错误我有它的基本形式,查看react文档以供参考,但仍然收到此错误。我已经准备好迎接面掌时刻了...

export function Header() {
  const [count, setCount] = useState(0)
  return <span>header</span>
}
6个回答

更新时间:2018-12 月

新版本react-hot-loader现已发布,链接Hooks 现在可以开箱即用了。感谢作者,theKashey。

看看这个样板https://github.com/ReeganExE/react-hooks-boilerplate

  • react-hooks
  • react热加载器
  • Webpack、Babel、ESLint Airbnb

上一个答案:

首先,确保你安装react@nextreact-dom@next

然后检查您是否正在使用react-hot-loader

在我的情况下,禁用热加载器和 HMR 可以让它工作。

请参阅https://github.com/gaearon/react-hot-loader/issues/1088

引:

是的。RHL 与钩子 100% 不兼容。这背后有几个原因:

SFC 正在转换为 Class 组件。有理由 - 能够在 HMR 上强制更新,只要 SFC 上没有“更新”方法。我正在寻找强制更新的其他方式(就像这样。所以 RHL 正在杀死 SFC。

“热替换渲染”。RHL 正在尝试做 React 的工作,渲染新旧应用程序,合并它们。所以,很明显,现在已经坏了。

我将起草一份 PR,以缓解这两个问题。它会起作用,但不是今天。

有一个更合适的修复方法,它可以工作 -冷 API

您可以为任何自定义类型禁用 RHL。

import { cold } from 'react-hot-loader';

cold(MyComponent);

搜索"useState/useEffect"内部组件源代码,并“冷”它。

更新:

根据react-hot-loader 维护者的更新,您可以尝试react-hot-loader@next将配置设置如下:

import { setConfig } from 'react-hot-loader';

setConfig({
  // set this flag to support SFC if patch is not landed
  pureSFC: true
});

感谢@loganfromlogan 的更新。

谢谢你指出这一点:)。我正在使用 react-hot-loader,所以它不起作用是有道理的。但是,我还不能 100% 确定没有其他事情发生。我将在 react-hot-loader 上关注此问题,并在发布修复程序后更新此问题。
2021-05-23 06:38:03
现在有一种方法可以使用 react-hot-loader 来实现这一点。参考 react-hot-loader 维护者的这篇评论,github.com/gaearon/ react-hot-loader/ issues/...
2021-06-04 06:38:03
另外,如果您将组件渲染为内联 jsx 函数调用,它仍然会导致错误,即使组件使用cold. 所以{MyComponent(props)}不会工作,但<MyComponent {...props} />会。
2021-06-05 06:38:03
我现在可以确认禁用 react-hot-loader 已解决此错误。
2021-06-07 06:38:03

我的问题是忘记更新react-dommodule。见问题

我也是!我正在使用 create-react-app 和 Typescript
2021-05-30 06:38:03
我正在使用 react 和 react-dom 版本 16.8.3 但仍然有同样的问题
2021-06-16 06:38:03

有同样的问题。我的问题与 React Router 相关。我不小心使用了

<Route render={ComponentUsingHooks} />

代替

<Route component={ComponentUsingHooks} />
我将组件渲染为 Route 元素内的子组件,<Route>{component}</Route>解决方案成功了
2021-05-27 06:38:03
我整个下午都在做这个。谢谢!
2021-06-08 06:38:03
这个评论也救了我的命。浪费了 3 个小时,把我的项目撕成碎片。是路由器打错字了
2021-06-09 06:38:03

我能够通过在组件文件中导入 React 的原始钩子,然后将它们传递到我的自定义钩子中来解决这个问题。出于某种原因,只有在我的自定义钩子文件中导入 React 钩子(如 useState)时才会发生错误。

我在我的组件文件中导入 useState:

import React, {useState} from 'react'; // import useState

import {useCustomHook} from '../hooks/custom-hook'; // import custom hook

const initialState = {items: []};
export default function MyComponent(props) {
    const [state, actions] = useCustomHook(initialState, {useState});
    ...
}

然后在我的钩子文件中:

// do not import useState here

export function useCustomHook(initialValue, {useState}) {
    const [state, setState] = useState(initialValue || {items: []});

    const actions = {
        add: (item) => setState(currentState => {
            const newItems = currentState.items.concat([item]);
            return {
                ...currentState,
                items: newItems,
            };
        }),
    };

    return [state, actions];
}

这种方法提高了我的钩子的可测试性,因为我不需要模拟 React 的库来提供原始钩子。相反,我们可以将模拟useState钩子直接传递到自定义钩子的函数中。我认为这提高了代码质量,因为你的自定义钩子现在没有与 React 库的耦合,允许更自然的函数式编程和测试。

我在使用Parcel 的 Hot Module Replacement时遇到了这个错误,并通过更新react-dom到它的 alpha 版本来修复

yarn add react-dom@16.7.0-alpha.0

看到这个问题。