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

目录
  • 开篇
  • 思路
  • 实现
  • 自定义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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 教你在react中创建自定义hooks

    一.什么是自定义hooks 逻辑复用 简单来说就是使用自定义hook可以将某些组件逻辑提取到可重用的函数中. 自定义hook是一个从use开始的调用其他hook的Javascript函数. 二.不使用自定义hook时 例1:当我们整个页面需要获取用户鼠标移动的坐标时,不使用hook的代码,我们可以这样写 const [position, setPosition] = useState({ x: 0, y: 0 }) useEffect(() => { const move = (e) => {

  • React自定义hook的方法

    目录 什么是hook 常用的有哪些hook 自定义hook 什么是hook Hook是 React 16.8 的新增特性.它通常与函数式组件同时使用.可以使函数式组件在不编写 class 的情况下,可以拥有class组件的状态.生命周期.引用等功能. 常用的有哪些hook React中常用的hooks有: useState 状态管理 useEffect 生命周期 useContext 跨组件数据传递 useRef 组件引用 .... 自定义hook 自定义hook其实就是自定义函数,与我们写函数

  • React Hook - 自定义Hook的基本使用和案例讲解

    目录 自定义Hook 自定义Hook基本使用 自定义Hook案例练习 获取Context数据 获取窗口滚轮数据 自定义Hook 自定义Hook基本使用 自定义Hook本质上只是一种函数代码逻辑的抽取,严格意义上来说,它本身并不算React的特性. 例如有这样一个需求: 所有的组件在创建和销毁时都进行打印 组件被创建: 打印组件被创建了; 组件被销毁: 打印组件被销毁了; 如果每个组件我们都单独编写是非常繁琐的, 并且有许多重复代码; 我们可以将实现这样逻辑相同的代码抽离为一个自定义的Hook i

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

    目录 开篇 思路 实现 自定义Hook-useForkRef 开篇 使用过 React 技术栈的同学相信都使用过 ref 传递给 render 中的元素,而在使用 React 封装组件时,会有这样一个场景: 组件将 props.children 作为 render 内容:组件内部会创建 ref 绑定到 props.children 上. 我们知道,元素上只能绑定一个 ref 属性引用,但对于上面这个场景,props.children 上可能已经存在一个 ref 属性,而组件内部定义的 ref 也

  • react中hook介绍以及使用教程

    前言 最近由于公司的项目开发,就学习了在react关于hook的使用,对其有个基本的认识以及如何在项目中去应用hook.在这篇博客中主要从以下的几个点进行介绍: hook简介 hook中常用api的使用 hook在使用过程中需要去注意的地方 hook中怎样去实现class组件中的声明周期函数 hook 首先介绍关于hook的含义,以及其所要去面对的一些场景 含义:Hook 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性

  • 一起来了解React的Hook

    目录 StateHook 声明多个state变量 那么,什么是Hook? EffectHook Hook使用规则 自定义Hook 其他Hook 总结 State Hook 这个例子用来显示一个计数器.当你点击按钮,计数器的值就会增加: import React, { useState } from 'react'; function Example() { // 声明一个叫 "count" 的 state 变量. const [count, setCount] = useState(0

  • React中hook函数与useState及useEffect的使用

    目录 1. 简介 2. useState使用 3. useEffect使用 useEffect发起网络请求 1. 简介 在 React 的世界中,有容器组件和 UI 组件之分,在 React Hooks 出现之前,UI 组件我们可以使用函数组件,无状态组件来展示 UI,而对于容器组件,函数组件就显得无能为力,我们依赖于类组件来获取数据,处理数据,并向下传递参数给 UI 组件进行渲染.React在v16.8 的版本中推出了 React Hooks 新特性,Hook是一套工具函数的集合,它增强了函数

  • vue3的自定义hook函数使用

    目录 自定义hook函数使用 vue3 hooks函数示例 官方示例代码---封装前 使用hooks函数封装后 hooks函数 自定义hook函数使用 使用Vue3的组合API封装的可复用的功能函数 自定义hook的作用类似于vue2中的mixin技术 自定义Hook的优势: 很清楚复用功能代码的来源, 更清楚易懂 需求1: 收集用户鼠标点击的页面坐标 这里先看一下大体项目结构: 这里的hooks下的文件是示例代码,public内的是测试数据 在启动项目后,测试public的data文件内的数据

  • 详解Vue 自定义hook 函数

    目录 定义 使用 封装发ajax请求的hook函数(ts版本) 定义 什么是hook? 本质是一个函数,把 setup 函数中使用的 Composition API (组合API)进行了封装 类似于 vue2.x 中的 mixin 自定义 hook 的优势: 复用代码,让 setup 中的逻辑更清楚易懂 使用 首先我们做一个功能,鼠标点击屏幕,获取坐标: <template> <h2>当前鼠标的坐标是:x:{{ point.x }},y:{{ point.y }}</h2&g

  • React自定义视频全屏按钮实现全屏功能

    目录 前言 一.绘制全屏按钮 二.编写点击事件 三.编写相关函数 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 React自定义视频全屏按钮,实现全屏功能. 一.绘制全屏按钮 绘制全屏按钮,并绑定点击事件: render() { return ( <div className={'fullfrequency'}> <img src={require("./全屏.png") } id="picts" onClick={thi

  • React hook实现简单的websocket封装方式

    目录 React hook实现websocket封装 react自定义hook解决websocket连接,useWebSocket 1.描述 2.代码 React hook实现websocket封装 新建websocket.ts文件 import {useState, useRef, useEffect} from 'react' const useWebsocket = ({ url:string, verify }) => {     const ws = useRef<WebSocket

随机推荐