"useState" cannot be called inside a callback. How to use state on "useCallback"?

Viewed 10076

I want to update state in Child component but it doesn't work. Actually, there're a lot of items. And I want to list each item with map.

The error:

React Hook "useState" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function

The code:

const renderItems = useCallback(() => {
  return items.map((item, idx) => {
    const { name } = room
    const [isCopiedURL, setIsCopiedURL] = useState(false)

    return (
      <li key={idx}>
        <CopyToClipboard
          text={item.name}
          onCopy={() => setIsCopiedURL(true)}
        >
          {item.name}
        </CopyToClipboard>
      </li>
    )
  })
}, [items])
1 Answers

You can convert the mapped return value to a component and then use useState within it since hooks are meant to be used within functional components.

According to the rules of rules you can use them within functions such as map in your case

const Item = ({room, item}) => {
    const { name } = room
    const [isCopiedURL, setIsCopiedURL] = useState(false)

    return (
      <li key={idx}>
        <CopyToClipboard
          text={item.name}
          onCopy={() => setIsCopiedURL(true)}
        >
          {item.name}
        </CopyToClipboard>
      </li>
    )
}

...
const renderItems = useCallback(() => {
  return items.map((item, idx) => {
     return <Item room={room} item={item} key={idx} />
  })
}, [items])
...
Related