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;


目录
相关文章
|
9月前
|
前端开发 JavaScript
react常用的hooks有哪些?
react常用的hooks有哪些?
101 0
|
4月前
|
前端开发 开发者
React 提供的其他重要 Hooks
【10月更文挑战第20天】React 提供了一系列强大的 Hooks,除了 `useRef` 之外,还有许多其他重要的 Hooks,它们共同构成了函数式组件开发的基础。
49 6
|
4月前
|
前端开发 JavaScript 开发者
React Hooks
10月更文挑战第13天
52 1
|
9月前
|
缓存 前端开发 JavaScript
【第28期】一文学会使用React Hooks
【第28期】一文学会使用React Hooks
66 0
|
9月前
|
前端开发 JavaScript
React都有哪些hooks?
useState:用于在函数组件中使用状态(state)。它返回一个数组,第一个元素是当前状态的值,第二个元素是更新状态的函数。可以通过调用这个函数来更新状态的值。
64 0
|
9月前
|
存储 缓存 前端开发
React hooks介绍及使用
React hooks介绍及使用
89 0
|
缓存 前端开发 JavaScript
React Hooks 的介绍
React Hooks 的介绍
|
前端开发
React Hooks 在使用上有哪些限制?
React Hooks 在使用上有哪些限制?
222 0
|
前端开发 API
React-Hooks-useImperativeHandle
React-Hooks-useImperativeHandle
77 0
|
JavaScript UED
React-Hooks-useLayoutEffect
React-Hooks-useLayoutEffect
62 0