0

I got error: "Invalid hook call. Hooks can only be called inside of the body of a function component." in react function:

interface Items {
  items: any[]
}

const [items, setItems] = useState<Items>();

const ItemsList: React.FC<Items> = ({ items }) => {
  useEffect(() => {
    const response = Http.get<Items>(url).then(res => setItems(res)) || [] as Items[]
  }, []) //something wrong with this hook?

  return (
      <ul>
        {items.map((item) => {
          return (
            <ItemPreview key={item.id} item={item}/>
          );
        })}
      </ul>
  )
}

export default ItemsList

I can't understand what I did wrong? can anyone show me where is error?

Lex2000
  • 155
  • 1
  • 1
  • 12
  • pretty much exactly what the error message says: you're calling the `useState` hook before your function component is declared. – Matt Morgan Jan 14 '21 at 17:20
  • 3
    Move `const [items, setItems] = useState();` right above `useEffect(() => {` and below `ItemsList: React.FC`. – Sam R. Jan 14 '21 at 17:21

1 Answers1

1

You need to call React Hooks from within a component, like so:

interface Items {
  items: any[]
}

const ItemsList: React.FC<Items> = ({ items }) => {
  const [items, setItems] = useState<Items>();
 
  useEffect(() => {
    const response = Http.get<Items>(url).then(res => setItems(res)) || [] as Items[]
  }, []);

  return (
      <ul>
        {items.map((item) => {
          return (
            <ItemPreview key={item.id} item={item}/>
          );
        })}
      </ul>
  )
}

export default ItemsList

See the Rules of Hooks for more information:

Only Call Hooks from React Functions

Don’t call Hooks from regular JavaScript functions. Instead, you can:

  • ✅ Call Hooks from React function components.
  • ✅ Call Hooks from custom Hooks.
  • Thank you.I fixed error like @Sam R.said, before your answer (you need also remove ```{ items }``` ), and now I have another error :) "Object is possibly 'undefined'. In "items.map" line. – Lex2000 Jan 14 '21 at 17:40
  • This is correct. It might also be worth you checking out this blog post about avoiding race conditions when making api calls within a useEffect hook. https://flufd.github.io/avoiding-race-conditions-use-current-effect/ – Thomas Fox Jan 14 '21 at 17:41
  • @eu97 Not sure if it's of any use to you, but I use [use-async-resource](https://github.com/andreiduca/use-async-resource) with `` boundaries. – resynth1943 Jan 14 '21 at 17:43