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导致的报错
错误的用法

  1. function App() {
  2. const [loading, setLoading] = React.useState(false);
  3. if (loading) {
  4. return "loading .....";
  5. }
  6. useEffect(() => {
  7. if (condition) {
  8. doSomething();
  9. }
  10. }, []);
  11. return <div>component</div>;
  12. }

正确的用法

  1. function App() {
  2. const [loading, setLoading] = React.useState(false);
  3. useEffect(() => {
  4. if (condition) {
  5. doSomething();
  6. }
  7. }, []);
  8. if (loading) {
  9. return "loading .....";
  10. }
  11. return <div>component</div>;
  12. }

如果要提起 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的错误用法

  1. // ❌ 错误的用法
  2. if(condition) {
  3. useEffect(()=>{
  4. doSomething();
  5. }, []);
  6. }
  7. // 正确的用法
  8. useEffect(()=>{
  9. if(condition) {
  10. doSomething();
  11. }
  12. }, []);

不要提前 return,错误的用法❌

  1. function App() {
  2. const [name, setName] = useState('Mary');
  3. if (!name) return null;
  4. const [license, setLicense] = useState('A123456');
  5. return (<div />);
  6. }

✅正确的用法

  1. function App() {
  2. const [name, setName] = useState('Mary');
  3. const [license, setLicense] = useState('A123456');
  4. if (!name) return null;
  5. return (<div />);
  6. }

useEffect

An effect function must not return anything besides a function, which is used for clean-up. You returned: [object Object]