Uncaught Invariant Violation: Rendered fewer hooks than expected. This may be caused by an accidental early return statement
组件定义过的 useState,存在一部分没有被调用,导致最终 render 的 hooks 数量比预期的少
Uncaught Invariant Violation: Rendered more hooks than during the previous render.
Warning: React has detected a change in the order of Hooks called by LineChart. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks
原因:hooks函数组件,提前 return导致的报错
错误的用法
function App() {const [loading, setLoading] = React.useState(false);if (loading) {return "loading .....";}useEffect(() => {if (condition) {doSomething();}}, []);return <div>component</div>;}
正确的用法
function App() {const [loading, setLoading] = React.useState(false);useEffect(() => {if (condition) {doSomething();}}, []);if (loading) {return "loading .....";}return <div>component</div>;}
如果要提起 return,就使用 容器模式来渲染
hooks使用规则
https://reactjs.org/docs/hooks-rules.html
https://zh-hans.reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
- hook规则:只在最顶层使用 Hook
- 不要在循环、条件或嵌套函数中调用 Hooks
- 总是在React函数的顶层使用 Hooks
- 遵循此规则,可以确保每次呈现组件时都以相同的顺序调用钩子
- always use Hooks at the top level of your React function
hooks的错误用法
// ❌ 错误的用法if(condition) {useEffect(()=>{doSomething();}, []);}// 正确的用法useEffect(()=>{if(condition) {doSomething();}}, []);
不要提前 return,错误的用法❌
function App() {const [name, setName] = useState('Mary');if (!name) return null;const [license, setLicense] = useState('A123456');return (<div />);}
✅正确的用法
function App() {const [name, setName] = useState('Mary');const [license, setLicense] = useState('A123456');if (!name) return null;return (<div />);}
useEffect
An effect function must not return anything besides a function, which is used for clean-up. You returned: [object Object]
