反应:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

Posted

技术标签:

【中文标题】反应:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用【英文标题】:React: Invalid hook call. Hooks can only be called inside of the body of a function component 【发布时间】:2020-01-18 03:27:33 【问题描述】:

我花了 2 天时间试图了解错误在哪里,知道吗?

App.js

import React,  useState, useEffect from 'react';
import Menu from './components/Menu';


function App()   

    return (
        <Menu></Menu>    
    );


export default App;

菜单.js

import React,  useState, useContext  from 'react';
import Logout from './Logout';


function Menu() 
    return (
        <button onClick=() => Logout()>button</button>
    );


export default Menu;

注销.js

import React,  useContext, useState  from 'react';
export function Logout() 

    const [user, setUser] = useState();
    const [token, setToken] = useState();

    localStorage.removeItem("token");
    localStorage.removeItem("user");
    setToken();
    setUser();


export default Logout;

我使用函数顶部的钩子 (Logout()) 所以我不知道会发生什么。也许是因为我嵌套了组件? 因为如果我将代码从 logout.js 移动到 menu.js 它可以工作,但我试图将函数移动到其他文件,以便我可以在更多组件中使用它

错误在于: 无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。

  18 | 
  19 | 
> 20 | export function Logout() 
  21 | 
  22 |  const [user, setUser] = useState();
  23 |  const [token, setToken] = useState();

【问题讨论】:

您的注销组件没有返回数据。您可以将其转换为自定义钩子 你想在这里做什么onClick=() =&gt; Logout() 我认为Logout应该是纯JS函数而不是组件,尝试删除useState,它是Logout组件的setter。 这能回答你的问题吗? Invalid hook call. Hooks can only be called inside of the body of a function component 【参考方案1】:

像这样调用onClick回调:

<button onClick=() => Logout()>button</button>

等价于:

const anynomousFunc = () => 
  // Logout()
  const [user, setUser] = useState();
  const [token, setToken] = useState();

  localStorage.removeItem('token');
  localStorage.removeItem('user');
  setToken();
  setUser();
;

但请注意,anynomousFunc 不是反应组件,这会导致:

无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。

// Examples of equivalent (but not valid) calls with react components
<div attribute=<Logout/>>Example</div>
<div attribute=Logout()>Example</div>

要解决此问题,取决于您的应用程序逻辑,create a custom hook 将返回 function 并使用它。

【讨论】:

【参考方案2】:
function Menu() 
    const [user, setUser] = useState('');
    const [token, setToken] = useState('');

    const logout = () => 
      localStorage.removeItem("token");
      localStorage.removeItem("user");
      setToken('');
      setUser('');
    

    return (
        <button onClick=() => logout()>button</button>
    );

【讨论】:

问题是 Logout 是一个函数(不是反应组件),你不能在函数内部定义反应钩子

以上是关于反应:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用的主要内容,如果未能解决你的问题,请参考以下文章

React Hooks Mobx:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

从 Firebase 存储调用图像 - 无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

React 17:错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

React Native 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

反应钩子:无效的钩子调用

错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。 (React-hooks React-native)