美文网首页
react hooks 无限循环

react hooks 无限循环

作者: 折叠幸福 | 来源:发表于2021-06-28 17:02 被阅读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>
      );
    }
    

    参考文章

    相关文章

      网友评论

          本文标题:react hooks 无限循环

          本文链接:https://www.haomeiwen.com/subject/psoqultx.html