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

 更新时间:2021年05月17日 15:52:07   作者:赐你岁月如歌  
Hooks 是一种函数,该函数允许您从函数式组件 “勾住(hook into)” React 状态和生命周期功能。 Hooks 在类内部不起作用 - 它们允许你无需类就使用 React,本文带领大家学习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加入依赖数组的话,doSomething里面很可能会访问到otherValue1, otherValue2旧的变量引用,从而发生意想不到的错误(如果安装hooks相关eslint的话,会提示警告)。
  • 反之,如果把otherValue1, otherValue2加入依赖数组的话,这两个值改变的时候doSomething也会执行,这并不是我们想要的(我们只想引用他们的值,但不想它们触发doSomething)。

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依赖的资料请关注脚本之家其它相关文章!

相关文章

  • react中使用usestate踩坑及解决

    react中使用usestate踩坑及解决

    这篇文章主要介绍了react中使用usestate踩坑及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • React路由中的redux和redux知识点拓展

    React路由中的redux和redux知识点拓展

    这篇文章主要介绍了React路由中的redux和redux知识点拓展,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的朋友可以参考学习一下
    2022-08-08
  • react数据管理中的setState与Props详解

    react数据管理中的setState与Props详解

    setState 是 React 中用于更新组件状态(state)的方法,本文给大家介绍react数据管理中的setState与Props知识,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • webpack构建react多页面应用详解

    webpack构建react多页面应用详解

    这篇文章主要介绍了webpack构建react多页面应用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • React + Typescript领域初学者的常见问题和技巧(最新)

    React + Typescript领域初学者的常见问题和技巧(最新)

    这篇文章主要介绍了React + Typescript领域初学者的常见问题和技巧,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • React Native项目设置路径别名示例

    React Native项目设置路径别名示例

    这篇文章主要为大家介绍了React Native项目设置路径别名实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • React组件通信浅析

    React组件通信浅析

    这篇文章主要介绍了React组件通信,在开发中组件通信是React中的一个重要的知识点,本文通过实例代码给大家讲解react中常用的父子、跨组件通信的方法,需要的朋友可以参考下
    2022-12-12
  • antd踩坑之javascriptEnabled配置方式

    antd踩坑之javascriptEnabled配置方式

    这篇文章主要介绍了antd踩坑之javascriptEnabled配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • vite+react+tailwindcss的简单使用方式

    vite+react+tailwindcss的简单使用方式

    这篇文章主要介绍了vite+react+tailwindcss的简单使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 浅谈React中组件逻辑复用的那些事儿

    浅谈React中组件逻辑复用的那些事儿

    这篇文章主要介绍了浅谈React中组件逻辑复用的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05

最新评论