Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Invalid hook call. Hooks can only be called inside of the body of a function component

i have spent 2 days trying to understand where is the mistake, any idea?

App.js

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


function App() {  

    return (
        <Menu></Menu>    
    );
}

export default App;

Menu.js

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


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

export default Menu;

Logout.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;

im using the hooks on top of a function (Logout()) so i dont know what happens. maybe because im nesting components? because if i move the code from logout.js to menu.js it works but im trying to move the function to other file so i can use it in more components

the error is in: Invalid hook call. Hooks can only be called inside of the body of a function component.

  18 | 
  19 | 
> 20 | export function Logout() {
  21 | 
  22 |  const [user, setUser] = useState();
  23 |  const [token, setToken] = useState();
like image 497
gnutella Avatar asked Sep 17 '19 09:09

gnutella


2 Answers

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>
    );
}
like image 104
demkovych Avatar answered Oct 01 '22 01:10

demkovych


Calling onClick callback like this:

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

Is equivariant to:

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

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

But notice that anynomousFunc is not a react component, which leads to:

Invalid hook call. Hooks can only be called inside of the body of a function component.

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

To fix this, depending on your application logic, create a custom hook which will return a function and use it.

like image 43
Dennis Vash Avatar answered Oct 01 '22 02:10

Dennis Vash