React自定义Hook-useForkRef的具体使用

 更新时间:2022年03月07日 09:54:21   作者:明里人  
本文主要介绍了React自定义Hook-useForkRef的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

开篇

使用过 React 技术栈的同学相信都使用过 ref 传递给 render 中的元素,而在使用 React 封装组件时,会有这样一个场景:

组件将 props.children 作为 render 内容;组件内部会创建 ref 绑定到 props.children 上。

我们知道,元素上只能绑定一个 ref 属性引用,但对于上面这个场景,props.children 上可能已经存在一个 ref 属性,而组件内部定义的 ref 也会绑定到 props.children 上。
我们要想一种方式,将两者的 ref 都可以生效于元素上。

思路

首先我们回顾一下 React 创建 ref 的方式:

  • React.createRef():React 16.3 版本提供的 class 创建 ref 方式;
  • React.useRef():React Hooks 提供的 函数组件 创建 ref 方式;
  • 回调 Refs:传递一个函数作为元素的 ref 属性,此函数接收 React 组件实例或 HTML DOM 元素作为参数。

综合考虑,既然 回调 Refs 允许我们传递一个函数,并且接收元素实例作为这个函数的参数,那我们就可以定义一个这样的函数,在函数内编写我们的逻辑来处理 多个 ref 绑定元素实例的场景。(函数的灵活性)

实现

  • 编写一个函数(闭包函数),接收 props.children.ref 和 组件内 ref 作为参数;
  • 函数(闭包函数)需要 return 返回一个函数,这个函数将作为 回调 Refs 去作用于元素;
  • 在 return 的这个函数中,将函数参数(元素引用)绑定到 props.children.ref 和 组件内 ref 上。

上代码:

function forkRef(refA, refB) {
  return refValue => {
    setRef(refA, refValue);
    setRef(refB, refValue);
  };
}

function setRef(ref, value) {
  if (typeof ref === 'function') {
    ref(value);
  } else if (ref) {
    ref.current = value;
  }
}

在 setRef 中会针对创建 ref 的方式做不同处理,比如:React.createRef 和 React.useRef 创建的 ref 是一个具有 current 属性的对象。

使用:

const nodeRef = React.useRef(null); // 组件内部的 ref

const handleRef = forkRef(props.children.ref, nodeRef);

const childrenProps = { ref: handleRef };

return React.cloneElement(children, childrenProps);

自定义 Hook - useForkRef

在 Hook 函数组件中,我们可以借助于 React.memo() 优化一下 forkRef() 的逻辑,避免每次组件更新时都创建一个新的闭包函数。
下面我们使用 TS 编写一个 useForkRef:

import * as React from 'react';

interface MutableRefObject<T> {
  current: T;
}

type Ref<T> = ((instance: T | null) => void) | MutableRefObject<T> | null;

export function setRef(ref: Ref<unknown>, value: unknown) {
  if (typeof ref === 'function') {
    ref(value);
  } else if (ref) {
    ref.current = value;
  }
}

export default function useForkRef(refA: Ref<unknown>, refB: Ref<unknown>) {
  return React.useMemo(() => {
    if (refA == null && refB == null) {
      return null;
    }
    return (refValue: unknown) => {
      setRef(refA, refValue);
      setRef(refB, refValue);
    };
  }, [refA, refB]);
}

使用:

const nodeRef = React.useRef<HTMLElement>(null); // 组件内部的 ref
const handleRef = useForkRef(children.ref, nodeRef);

const childrenProps: any = { ref: handleRef };
React.cloneElement(children, childrenProps)

到此这篇关于React自定义Hook-useForkRef的具体使用的文章就介绍到这了,更多相关React Hook-useForkRe内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解React如何使用​​useReducer​​​高阶钩子来管理状态

    详解React如何使用​​useReducer​​​高阶钩子来管理状态

    useReducer是React中的一个钩子,用于替代 useState来管理复杂的状态逻辑,本文将详细介绍如何在React中使用 useReducer高阶钩子来管理状态,感兴趣的可以了解下
    2025-02-02
  • React新扩展函数setState与lazyLoad及hook介绍

    React新扩展函数setState与lazyLoad及hook介绍

    这篇文章主要介绍了React新扩展函数setState与lazyLoad及hook,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • React中常见的TypeScript定义实战教程

    React中常见的TypeScript定义实战教程

    这篇文章主要介绍了React中常见的TypeScript定义实战,本文介绍了Fiber结构,Fiber的生成过程,调和过程,以及 render 和 commit 两大阶段,需要的朋友可以参考下
    2022-10-10
  • React 组件性能最佳优化实践分享

    React 组件性能最佳优化实践分享

    这篇文章主要介绍了React组件性能最佳优化实践分享,React组件性能优化的核心是减少渲染真实DOM节点的频率,减少Virtual DOM比对的频率,更多相关内容需要的朋友可以参考一下
    2022-09-09
  • 使用Node搭建reactSSR服务端渲染架构

    使用Node搭建reactSSR服务端渲染架构

    这篇文章主要介绍了使用Node搭建reactSSR服务端渲染架构,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 关于react useState更新异步问题

    关于react useState更新异步问题

    这篇文章主要介绍了关于react useState更新异步问题,具有很好的参考价值,希望对大家有所帮助。以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    2022-08-08
  • react源码中的生命周期和事件系统实例解析

    react源码中的生命周期和事件系统实例解析

    这篇文章主要为大家介绍了react源码中的生命周期和事件系统实例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 你知道怎么基于 React 封装一个组件吗

    你知道怎么基于 React 封装一个组件吗

    这篇文章主要为大家详细介绍了React如何封装一个组件,使用antd的divider组件来讲解,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • Javascript之提高React性能的技巧

    Javascript之提高React性能的技巧

    一些刚开始学习 React,或者从其他框架转入 React 的开发者,一开始可能不会太关注性能。因为需要一些时间来发现新学习的框架的性能缺点。这篇文章主要介绍提高React性能的技巧,感兴趣的同学可以参考阅读
    2023-04-04
  • 基于React封装一个层次模糊效果的容器组件

    基于React封装一个层次模糊效果的容器组件

    这篇文章主要为大家详细介绍了如何基于React封装一个层次模糊效果的容器组件,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03

最新评论