不能在回调中调用 React Hook “useState”

Posted

技术标签:

【中文标题】不能在回调中调用 React Hook “useState”【英文标题】:React Hook "useState" cannot be called inside a callback 【发布时间】:2021-04-03 15:25:54 【问题描述】:

有没有另一种方法可以做到这一点,而不必将 useState 变量放在地图函数之外?

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>
    );
  );

【问题讨论】:

是的,只要把地图里面的jsx变成另一个组件。 【参考方案1】:

您可以定义一个自定义组件。


  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>
   )

【讨论】:

那么,如何使用单独组件中列表中的项目? 例如,列表包含名称,我将在哪里呈现名称列表? 就像item.createdAt一样,我将在哪里使用item.names 如果答案正确,你会打勾并投票吗? 让我们continue this discussion in chat。【参考方案2】:

您可以改为将数组置于状态:

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>)
);

【讨论】:

以上是关于不能在回调中调用 React Hook “useState”的主要内容,如果未能解决你的问题,请参考以下文章

React Hook - 无法在子组件 onComplete 回调中调用父组件调度

我打破了React Hook必须按顺序不能在条件语句中调用的枷锁!

React+Typescript:修复 UseEffect Hook(回调+清理函数错误)

项目上的 React Hook

react使用hook——useState的坑

React Hook 下setState的回调