[英]adding useMemo or useCallbacks to the map component breaks the code with error "Rendered more hooks than during 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.