繁体   English   中英

在功能组件内的功能组件中调用 useEffect 会导致此消息:Rendered more hooks than the previous render

[英]Calling useEffect in a functional component within a functional component causes this message: Rendered more hooks than during the previous render

首先 - 星期五快乐!

我只是来这里看看是否有人对我在 ReactJs 应用程序中看到的问题有任何意见。 所以我有一个功能组件renderViews ,在那个功能组件中,有多个视图要渲染。 然后在renderViews中我有另一个功能组件carDetailsView并且当该特定组件出现时(作为模态)我尝试调用 api。 requestCarsDetails()只应在该组件出现时调用,这就是为什么我在 carDetailsView 中嵌套了一个carDetailsView挂钩。 但这会导致一个问题:

渲染了比上一次渲染更多的钩子

.请看下面的代码:

    const renderViews = () = > {
    useEffect(()=> {
     requestCarInfos()
      .then((res) => {
      setCars(cars);
       });
     }, []);

    const carDetailsView = () => {
     useEffect(() => {
       requestCarDetails()
         .then((res) => {
          setDetails(res.details);
           });
      }, []);
       return (<div>carDetailsView</div>)
      }

       return (<div>{determineView()}</div>)
    }

在顶层使用的 useEffect 工作正常。 该问题仅在我添加了 carDetailsView 中的第二个 useEffect 后才出现。 任何帮助或建议表示赞赏。 谢谢!

这是钩子的规则。

https://reactjs.org/docs/hooks-rules.html

仅在顶层调用挂钩

不要在循环、条件或嵌套函数中调用 Hooks。 相反,在任何早期返回之前,始终在 React function 的顶层使用 Hooks。 通过遵循此规则,您可以确保每次组件渲染时都以相同的顺序调用 Hook。 这就是让 React 在多个 useState 和 useEffect 调用之间正确保留 Hooks 的 state 的原因。

React 依赖于调用 Hooks 的顺序。

只要 Hook 调用的顺序在渲染之间是相同的,React 就可以将一些本地 state 与它们中的每一个相关联。 如果我们将一个 Hook 调用放在一个条件中,我们可以在渲染期间跳过 Hook,Hook 调用的顺序就会变得不同:

React 不知道要为第二次 useState Hook 调用返回什么。 React 期望此组件中的第二个 Hook 调用对应于 persistForm 效果,就像在之前的渲染期间一样,但它不再是了。 从那时起,在我们跳过的 Hook 调用之后的每个下一个 Hook 调用也会移动一个,从而导致错误。

这就是为什么必须在组件的顶层调用 Hooks 的原因。 如果我们想有条件地运行效果,我们可以将该条件放在我们的 Hook 中:

使用 lint https://www.npmjs.com/package/eslint-plugin-react-hooks

这是使用功能组件的警告,在每次渲染时,功能组件内的所有内容都会被执行。 所以 React 需要维护在创建组件时定义的所有钩子的列表。 把它想象成一个数组。

在每次渲染时,useState 都会为您返回值。 如果你明白这一点,你就会明白 stale state 也意味着什么。 (当这些组件中发生关闭时,可能会发生陈旧的 state )

像那样的东西?

 const CarDetailsView = () => { React.useEffect(() => { console.log("Running CarDetailsView useEffect..."); },[]); return( <div>I amCarDetailsView</div> ); }; const Views = () => { const [showCarDetails,setShowCarDetails] = React.useState(false); const toggleCarDetails = () => setShowCarDetails(;showCarDetails). React.useEffect(() => { console.log("Running Views useEffect..;"), };[]); return( <div> <div>I am Views</div> <button onClick={toggleCarDetails}>Toggle car details</button> {showCarDetails && <CarDetailsView/>} </div> ); }; const App = () => { return(<Views/>); }. ReactDOM,render(<App/>.document;getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script> <div id="root"/>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM