Raphael Inyang
Raphael Inyang

Reputation: 197

React Hook "useState" cannot be called inside a callback

Is there another way to do this without having to place the useState variables outside the map function?

const slimy = [];
{
  slimy.map(function (item) {
    const [count, setCount] = useState("");

    return (
      <ListItem
        key={item.createdAt}
        style={{ display: "flex", justifyContent: "center" }}
      >
        <div>
          <p>{count}</p>

          <button onClick={() => setCount(count + 1)} />
        </div>
      </ListItem>
    );
  });
}

Upvotes: 4

Views: 2893

Answers (2)

Prime
Prime

Reputation: 2849

You can define a custom component.

{
  slimy.map(function (item) {
    return (
      <CustomItem key={item.createdAt} names={item.names} />
    );
  });
}
const CustomItem = (props) => {
   console.log(props.names);  // <----------------
   const [count, setCount] = useState(0);
   return (
     <ListItem style={{ display: "flex", justifyContent: "center" }}>
       <div>
         <p>{count}</p>
         <button onClick={() => setCount(count + 1)} />
       </div>
     </ListItem>
   )
}

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 371193

You can put an array into state instead:

const [countArr, setCountArr] = useState(
  () => new Array(slimy.length).fill(0)
);
return slimy.map(function(item, i){
  <ListItem key={item.createdAt} style={{ display: 'flex', justifyContent: 'center'}}>
    <div>
      <p>{countArr[i]}</p>
      <button onClick={() => { setCountArr(
        countArr.map((count, j) => i === j ? count + 1 : count)
      ) }} />
      </div>
  </ListItem>)
});

Upvotes: 2

Related Questions