react hooks 无限循环

2021-06-28  本文已影响0人  折叠幸福

新手刚用hooks的时候,如果没开eslint,比较容易写出无线循环,比如下面代码

export default function App() {
  const [count, setCount] = useState(0); 
  const value = { name: 1 };

  useEffect(() => {
    setCount(Math.random()); 
    alert("render 1");
  }, [value]);
  return (
    <div className="App">
      <h1>xxxx 1</h1>
      <h2>xxxx 1 xxxx</h2>
    </div>
  );
}

造成循环的原因是:组件初始化渲染->useEffect执行->setCount触发组件重新渲染->useEffect执行->setCount触发组件重新渲染...
解决的方法有两种:
1.useMemo() 或者 useCallback()

export default function App() {
  const [count, setCount] = useState(0); 
  const value = useMemo( ()=>{
     return { name: 1 };
},[])

  useEffect(() => {
    setCount(Math.random()); 
    alert("render 1");
  }, [value]);
  return (
    <div className="App">
      <h1>xxxx 1</h1>
      <h2>xxxx 1 xxxx</h2>
    </div>
  );
}

useMemo :返回一个缓存值,仅会在依赖项改变时才重新计算返回.
本例子中useMemo 依赖项因为回调函数太简单,所以填空
如果依赖的值需要调用一个函数来生成,用useCallback即可

export default function App() {
  const [count, setCount] = useState(0); 

  function doSomething(){
       return { name: 1 };
  }
  const value = useCallback( ()=>{
      doSomething()
  },[] )

  useEffect(() => {
    setCount(Math.random()); 
    alert("render 1");
  }, [value]);
  return (
    <div className="App">
      <h1>xxxx 1</h1>
      <h2>xxxx 1 xxxx</h2>
    </div>
  );
}

如果你定义了一个变量,满足下面的条件就最好用useMemo和useCallback给包裹住:

  1. 它不是状态,也就是说,不是用useState定义的(redux中的状态实际上也是用useState定义的)
  2. 它不是基本类型
  3. 它会被放在useEffect的依赖列表里 || 自定义hook的返回值

说一下第3条,中间的两个竖线是 或,也就是两者满足其一第3条就成立。自定义hook的返回值也成立是因为,你不知道自定义hook的返回值将会被用在哪里,它可能会被用在依赖也可能不会,所以干脆都加上

代码简单不复杂 就用useMemo来生成变量,复杂需要调用第三方函数就用useCallback

2.更改依赖
useEffect依赖对象改成依赖对象某个属性

export default function App() {
  const [count, setCount] = useState(0); 
  const value = { name: 1 };

  useEffect(() => {
    setCount(Math.random()); 
    alert("render 1");
  }, [value.name]);
  return (
    <div className="App">
      <h1>xxxx 1</h1>
      <h2>xxxx 1 xxxx</h2>
    </div>
  );
}

参考文章

上一篇下一篇

猜你喜欢

热点阅读