React-Hooks之useImperativeHandler

简介: React-Hooks之useImperativeHandler
1.什么是useImperativeHandle Hook?

useImperativeHandle可以让你在使用ref 时自定义暴露给父组件的实例值,我的理解就是不让外界随便对通过ref拿到的元素进行操作,maybe我们可以称之为“权限配置"

这里出现了ref,小单简单地回顾一下前几天学习的useRef,可以知道ref就是帮助我们获取某个元素而设定的。

But!!!!!我记得当时说过useRef并不能帮助我们拿到函数式组件,只能帮我们拿到函数式组件中的某个元素,让小单来验证一下吧。

//1. 构造一个函数式组件
import React, {useRef} from 'react';
function Home(props) {
    return (
        <div>
            <p>Home</p>
            <input type="text" placeholder={'请输入内容'}/>
        </div>
    )
// App.js
function App() {
  // 2.创建一个ref
    const appRef = useRef();
    function btnClick() {
//打印一下ref拿到的元素
         console.log(appRef);
         console.log(appRef.current);
    }
    return (
        <div>
            <Home ref={appRef}/>
            <button onClick={()=>{btnClick()}}>获取</button>
        </div>
    )
}

结果如下:可以发现useRef拿不到函数式组件Home,但是控制台给了我们提示,可以使用React.forward()

62.png

函数式组件无法通过useref直接获取.png


让我们跟着控制台的提示来尝试一下吧~

我对代码进行了改进

React.forward()和mome一样是一个高阶组件

主要改进

const ForwardHome = forwardRef(Home);

代码如下:

import React, {useRef, forwardRef} from 'react';
//1. 构造一个函数式组件
function Home(props) {
    return (
        <div>
            <input type="text" placeholder={'请输入内容'}/>
        </div>
    )
// App.js
function App() {
  // 2.创建一个ref
    const appRef = useRef();
    function btnClick() {
//打印一下ref拿到的元素
         console.log(appRef);
         console.log(appRef.current);
    }
    return (
        <div>
//用forwardRef返回的ForwardHome代替Home
            <ForwardHome ref={appRef}/>
            <button onClick={()=>{btnClick()}}>获取</button>
        </div>
    )
}

结果如下,这表明我们此时我们通过React.forward()可以拿到函数式组件了

61.png

可以获取函数式组件.png


既然可以拿到函数式组件了,那意味着我们也可以对其进行操作,试一下吧~

将btnClick方法添加对其操作的代码:此时页面会自动聚焦并显示设置的文本:

function btnClick() {
        //打印一下ref拿到的元素
         console.log(appRef);
         console.log(appRef.current);
      //对拿到的元素进行操作
        appRef.current.focus();
        appRef.current.value = '华科上岸,小单冲冲冲!';
    }

但是问题又来了,如果说我并不想让外界通过以上方法随意的对拿到的函数式组件进行操作,只可以进行部分操作(类似于权限控制的说法)该怎么做呢?

此时useImperativeHandler就诞生了!

用法:

1. 导入useImperativeHandle
import React, {useRef, forwardRef, useImperativeHandle} from 'react';
2.创建
//接受的第一个参数是一个ref,第二个参数是一个回调函数,返回其允许进行的操作
useImperativeHandle(appRef, ()=>{
        return {
            myFocus: ()=>{
                inputRef.current.focus();
            }
        }
    });

具体代码:

import React, {useRef, forwardRef, useImperativeHandle} from 'react';
function Home(props, appRef) {
    const inputRef = useRef();
    useImperativeHandle(appRef, ()=>{
        return {
            myFocus: ()=>{
                inputRef.current.focus();
            }
        }
    });
    return (
        <div>
            <p>Home</p>
            <input ref={inputRef} type="text" placeholder={'请输入内容'}/>
        </div>
    )
}
const ForwardHome = forwardRef(Home);
function App() {
    const appRef = useRef();
    function btnClick() {
        // console.log(appRef);
        // console.log(appRef.current);
        appRef.current.focus();
        appRef.current.value = '华科上岸,小单冲冲冲!';
    }
    return (
        <div>
            <ForwardHome ref={appRef}/>
            <button onClick={()=>{btnClick()}}>获取</button>
        </div>
    )
}
export default App;

此时仍然通过 appRef.current.focus();进行操作就不可以,因为useImperativeHandle第二个参数返回的东西里没有这个操作


60.png

实现了ref的权限控制.png

终极方案

调用useImperativeHandle定义的myFocus可以实现自动聚焦

import React, {useRef, forwardRef, useImperativeHandle} from 'react';
function Home(props, appRef) {
    const inputRef = useRef();
    useImperativeHandle(appRef, ()=>{
        return {
            myFocus: ()=>{
                inputRef.current.focus();
            }
        }
    });
    return (
        <div>
            <p>Home</p>
            <input ref={inputRef} type="text" placeholder={'请输入内容'}/>
        </div>
    )
}
const ForwardHome = forwardRef(Home);
function App() {
    const appRef = useRef();
    function btnClick() {
        // console.log(appRef);
        // console.log(appRef.current);
        // appRef.current.focus();
       // appRef.current.value = '华科上岸,小单冲冲冲!';
        appRef.current.myFocus();
    }
    return (
        <div>
            <ForwardHome ref={appRef}/>
            <button onClick={()=>{btnClick()}}>获取</button>
        </div>
    )
}
export default App;


目录
相关文章
|
数据可视化 数据挖掘 关系型数据库
招聘信息数据分析及可视化|以51JOB为例进行
招聘信息数据分析及可视化|以51JOB为例进行
719 0
|
Java 关系型数据库 MySQL
windows部署DataX及运行dataX_WEB
windows部署DataX及运行dataX_WEB
4506 0
windows部署DataX及运行dataX_WEB
|
Java API
可能导致CPU占用率过高的场景与解决方案
尽量减少无限循环、让循环执行得慢一点(sleep)
|
6天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
16天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
10天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
625 217
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
863 61
|
8天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1362 157