为了账号安全,请及时绑定邮箱和手机立即绑定

尽管数组为空,但 React useEffect 无限循环

尽管数组为空,但 React useEffect 无限循环

至尊宝的传说 2023-10-14 10:04:59
我有一个反应钩子。该钩子具有子钩子,子钩子在生成时会为自己生成一个 ID。该 ID 始终是唯一的,因为每次创建新的子钩子时它都会加 1。const App = () => {  const [ idCounter, setIdCounter ] = React.useState(0);      const genId = () => {    setIdCounter( id => id + 1 );    return `ID-${idCounter}`;  }    const SomeComponent = () => {    const [ componentId, setComponentId ] = React.useState(null);        React.useEffect(() => {      let generatedId = genId();      setComponentId( id => generatedId );      console.log(`generated '${generatedId}'`)    }, []);        return <div>nothing works</div>  }    return <SomeComponent />};这会一遍又一遍地循环并记录生成的 id。它到底为什么要这么做?useEffect()依赖于...什么都没有!!它应该只运行一次,不是吗?我怎样才能避免这种情况发生?我希望将来能够SomeComponent从内部创建一些。App
查看完整描述

2 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

首先,首先,

我希望将来能够从应用程序内创建多个 SomeComponent 。

在使用 React 时,这(至少是你这样做的方式)是不可能的或根本不应该做的。您不能在另一个组件内创建一个组件。

目前,您陷入无限循环的原因useEffect可能有多种。可能它没有位于最高范围,但我的猜测是发生以下情况:

genId()被调用,状态被更新,重新渲染被初始化(因为状态更新),并const SomeComponent = () => {...}再次初始化,从而useEffect再次激活。

要解决这个问题,首先要从内部创建的事物中删除<SomeComponent /><App />它们,它们应该完全分开。其次,将该genId函数作为prop传递,并将其添加到useEffect依赖项列表中,因为您需要它。

这将是一个很好的开始,因为现在代码在语义上和规则上都是正确的。

const SomeComponent = ({ genId }) => {

  const [ componentId, setComponentId ] = React.useState(null);

    

  React.useEffect(() => {

    let generatedId = genId();

    setComponentId(generatedId);

    console.log(`generated '${generatedId}'`)

  }, [genId]);

    

  return <div>nothing works</div>

}



const App = () => {

  const [ idCounter, setIdCounter ] = React.useState(0);

  

  

  const genId = () => {

    setIdCounter( id => id + 1 );

    return `ID-${idCounter}`;

  }

  

  

  return <SomeComponent genId={genId} />

};


查看完整回答
反对 回复 2023-10-14
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

我不会回答这个问题,只是指出子组件有一些缺点。你的子组件几乎不可能进行单元测试。也许您可以将其移至顶级组件并接受generatedId作为道具


const SomeComponent = ({generatedId}) => {

    const [ componentId, setComponentId ] = React.useState(null);


    React.useEffect(() => {


      setComponentId( id => generatedId );

      console.log(`generated '${generatedId}'`)

    }, []);


    return <div>nothing works</div>

}


const App = () => {

  const [ idCounter, setIdCounter ] = React.useState(0);

  

  

  const genId = () => {

    setIdCounter( id => id + 1 );

    return `ID-${idCounter}`;

  }

  


  

  return <SomeComponent  generatedId={genId()}/>

};


查看完整回答
反对 回复 2023-10-14
  • 2 回答
  • 0 关注
  • 76 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信