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])
To use callback in the useState hook, we need to use the useEffect hook that triggers after state update and call the function after that. We need to pass state in the useEffect Dependency Array. useEffect is triggered when the state updates and then calls the inside function immediately.
We must remember is that the setState function must not be passed to the useCallback dependency array. The React team suggests this: "React guarantees that setState function identity is stable and won't change on re-renders. This is why it's safe to omit from the useEffect or useCallback dependency list."
The key takeaway here is that useCallback returns you a new version of your function only when its dependencies change, saving your child components from automatically re-rendering every time the parent renders.
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])
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With