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]