0

I am learning React by making a motor cycle spec searching web application, and I am trying to import fetched data into makePicker.jsx to essentially make a drop down menu with those data.

However I am getting an error message saying:

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

I am not sure what applies to my situation. Can you see why?

makePicker.jsx

import React, {useState, useEffect} from 'react'; import {NativeSelect, FormControl} from '@material-ui/core'; import styles from './makePicker.module.css'; import { makeList } from '../../api'; const MakePicker = ()=>{ const [fetchedMakes, setFetchedMakes] = useState([]); useEffect(()=>{ const fetchAPI = async()=>{ setFetchedMakes(await makeList()); } fetchAPI(); },[]) return ( <h1>makePicker</h1> ); } export default MakePicker;

App.js

import logo from './logo.svg'; import './App.css'; import {fetchData, makeList} from './api/index'; import React, {Component} from 'react'; import MakePicker from './components/makePicker/makePicker'; class App extends React.Component{ state = { data:[], makes:[], } async componentDidMount(){ // const fetchedData = await fetchData(); const fetchedMakeList = await makeList(); this.setState({makes:fetchedMakeList}); } render(){ return ( <div className="App"> <header className="App-header"> {MakePicker()}; <h1>Some line-ups from YAMAHA</h1> {this.state.makes.map(make=>{ return <p>{make.name}</p> })} <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Open React </a> </header> </div> ); } } export default App; 

Please let me know if need more information from my project.

5
  • 5
    The code provided does not throw that error. Commented May 5, 2022 at 8:29
  • How did you call MakePicker in another component? Commented May 5, 2022 at 8:29
  • I agree with the commenters above: we need to see the other files because this code won't produce any hooks errors. Just guessing: are you using hooks in your API route? Because that will throw an error Commented May 5, 2022 at 8:51
  • This happens when you use Hooks outside jsx component. This answer can be useful stackoverflow.com/questions/62077729/… Commented May 5, 2022 at 8:57
  • MakePicker is a component; not the function. So instead of {MakePicker()}; define as JSX element i.e. <MakePicker /> Commented May 5, 2022 at 9:01

2 Answers 2

2

According to your code in App.jsx and following the naming convention of React's component, you should import it with the first-capitalized-letter name like below

import MakePicker from './components/makePicker/makePicker'; 

You're also calling {makePicker()}; which is not a proper way for component rendering. You should modify it to

<MakePicker/> 

Full possible change can be

import logo from './logo.svg'; import './App.css'; import {fetchData, makeList} from './api/index'; import React, {Component} from 'react'; import MakePicker from './components/makePicker/makePicker'; class App extends React.Component{ state = { data:[], makes:[], } async componentDidMount(){ // const fetchedData = await fetchData(); const fetchedMakeList = await makeList(); this.setState({makes:fetchedMakeList}); } render(){ return ( <div className="App"> <header className="App-header"> <MakePicker/> <h1>Some line-ups from YAMAHA</h1> {this.state.makes.map(make=>{ return <p>{make.name}</p> })} <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Open React </a> </header> </div> ); } } export default App; 

To elaborate more why you get this error

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

When you call makePicker(), it's actually triggering a Javascript's function (not React's component as you expected), but useEffect is only available in React's components. That's why when you try to run code, the compiler is thinking makePicker is calling useEffect invalidly.

Sign up to request clarification or add additional context in comments.

Comments

1

Their is a problem lies on your useEffect

update the code like this and try it out:

 const fetchAPI = async()=>{ const res = await makeList().then((data) => { setFetchedMakes(data) }).catch((err) => console.log(err)) } useEffect(()=>{ fetchAPI(); },[]) 

here i placed the asynchronous function outside of the useEffect

Also make MakePicker as an JSX element like this: <MakePicker />

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.