当前位置:编程学习 > > 正文

reacthooks基础使用(React 小技巧教你如何摆脱hooks依赖烦恼)

时间:2022-03-31 19:15:46类别:编程学习

reacthooks基础使用

React 小技巧教你如何摆脱hooks依赖烦恼

react项目中,很常见的一个场景:

  • const [watchValue, setWatchValue] = useState('');
    const [otherValue1, setOtherValue1] = useState('');
    const [otherValue2, setOtherValue2] = useState('');
    
    useEffect(() => {
        doSomething(otherValue1, otherValue2);
    }, [watchValue, otherValue1, otherValue2]);
    
  • 我们想要watchValue改变的时候执行doSomething,里面会引用其他值otherValue1, otherValue2

    这时有个让人烦恼的问题:

    otherValue1, otherValue2变成ref可以解决这个问题:

  • const [watchValue, setWatchValue] = useState('');
    const other1 = useRef('');
    const other2 = useRef('');
    
    // ref可以不加入依赖数组,因为引用不变
    useEffect(() => {
        doSomething(other1.current, other2.current);
    }, [watchValue]);
    
  • 这样other1, other2的变量引用不会变,解决了前面的问题,但是又引入了一个新的问题:other1, other2的值current改变的时候,不会触发组件重新渲染(useRef的current值改变不会触发组件渲染),从而值改变时候界面不会更新!

    这就是hooks里面的一个头疼的地方,useState变量会触发重新渲染、保持界面更新,但作为useEffect的依赖时,又总会触发不想要的函数执行。useRef变量可以放心作为useEffect依赖,但是又不会触发组件渲染,界面不更新。
    如何解决?

    可以将useRefuseState的特性结合起来,构造一个新的hooks函数: useStateRef

  • import { useState, useRef } from "react";
    
    // 使用 useRef 的引用特质, 同时保持 useState 的响应性
    type StateRefObj<T> = {
      _state: T;
      value: T;
    };
    export default function useStateRef<T>(
      initialState: T | (() => T)
    ): StateRefObj<T> {
      // 初始化值
      const [init] = useState(() => {
        if (typeof initialState === "function") {
          return (initialState as () => T)();
        }
        return initialState;
      });
      // 设置一个 state,用来触发组件渲染
      const [, setState] = useState(init);
      
      // 读取value时,取到的是最新的值
      // 设置value时,会触发setState,组件渲染
      const [ref] = useState<StateRefObj<T>>(() => {
        return {
          _state: init,
          set value(v: T) {
            this._state = v;
            setState(v);
          },
          get value() {
            return this._state;
          },
        };
      });
      
      // 返回的是一个引用变量,整个组件生命周期之间不变
      return ref;
    }
    
  • 这样,我们就能这样用:

  • const watch = useStateRef('');
    const other1 = useStateRef('');
    const other2 = useStateRef('');
    
    // 这样改变值:watch.value = "new";
    
    useEffect(() => {
        doSomething(other1.value, other2.value);
       // 其实现在这三个值都是引用变量,整个组件生命周期之间不变,完全可以不用加入依赖数组
       // 但是react hooks的eslint插件只能识别useRef作为引用,不加人会警告,为了变量引用安全还是加入
    }, [watch.value, other1, other2]);
    
  • 这样,watch, other1,other2useRef的引用特性,不会触发doSomething不必要的执行。又有了useState的响应特性,改变.value的时候会触发组件渲染和界面更新。
    我们想要变量改变触发doSomething的时候,就把watch.value加入依赖数组。我们只想引用值而不想其触发doSomething的时候,就把变量本身加入数组。

    以上就是React 小技巧教你如何摆脱hooks依赖烦恼的详细内容,更多关于React hooks依赖的资料请关注开心学习网其它相关文章!

    标签:
    上一篇下一篇

    猜您喜欢

    热门推荐