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.jsfunction 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()
让我们跟着控制台的提示来实验一下吧~
我对代码举行了改进
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.jsfunction 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()可以拿到函数式组件了
既然可以拿到函数式组件了,那意味着我们也可以对其举行使用,试一下吧~
将btnClick方法添加对其使用的代码:此时页面会主动聚焦并体现设置的文本:
function btnClick() { //打印一下ref拿到的元素 console.log(appRef); console.log(appRef.current); //对拿到的元素举行使用 appRef.current.focus(); appRef.current.value = '华科登岸,小单冲冲冲!'; }但是标题又来了,假如说我并不想让外界通过以上方法随意的对拿到的函数式组件举行使用,只可以举行部分使用(雷同于权限控制的说法)该怎么做呢?
此时useImperativeHandler就诞生了!
用法:
1. 导入useImperativeHandleimport 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第二个参数返回的东西里没有这个使用
终极方案
调用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; |