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

我有一个反应钩子。

该钩子具有子钩子,子钩子在生成时会为自己生成一个 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


至尊宝的传说
浏览 128回答 2
2回答

守着一只汪

首先,首先,我希望将来能够从应用程序内创建多个 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} />};

慕尼黑8549860

我不会回答这个问题,只是指出子组件有一些缺点。你的子组件几乎不可能进行单元测试。也许您可以将其移至顶级组件并接受generatedId作为道具const SomeComponent = ({generatedId}) => {&nbsp; &nbsp; const [ componentId, setComponentId ] = React.useState(null);&nbsp; &nbsp; React.useEffect(() => {&nbsp; &nbsp; &nbsp; setComponentId( id => generatedId );&nbsp; &nbsp; &nbsp; console.log(`generated '${generatedId}'`)&nbsp; &nbsp; }, []);&nbsp; &nbsp; return <div>nothing works</div>}const App = () => {&nbsp; const [ idCounter, setIdCounter ] = React.useState(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const genId = () => {&nbsp; &nbsp; setIdCounter( id => id + 1 );&nbsp; &nbsp; return `ID-${idCounter}`;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return <SomeComponent&nbsp; generatedId={genId()}/>};
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript