一、专栏介绍 👏👏
欢迎加入本专栏!本专栏将引领您快速上手React,让我们一起放弃放弃的念头,开始学习之旅吧!我们将从搭建React项目开始,逐步深入讲解最核心的hooks,以及React路由、请求、组件封装以及UI(Ant Design)框架的使用。让我们一起掌握React,开启前端开发的全新篇章。
二、useImperativeHandle 📀📀
useImperativeHandle
是 React 中的一个 Hook,它能让你自定义由 ref 暴露出来的句柄。
文档中明确的说明了,默认情况下,组件不会将它们的 DOM 节点暴露给父组件。举例来说,如果你想要 MyInput
的父组件 能访问到 <input>
DOM 节点,你必须选择使用 forwardRef:。
所以这里我们需要先了解forwardRef
三、forwardRef 💾💾
forwardRef
允许组件使用 ref 将 DOM 节点暴露给父组件。使用 forwardRef()
让组件接收 ref 并将其传递给子组件。
TypeScript
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
return <input {...props} ref={ref} />;
});
四、两者集合以后的案例 📷📷
4.1、子组件 👇👇
子组件的源码接收三个参数:placeholder占位符、onchange事件以及ref属性。其中,ref属性是由父组件传递给子组件的,与子组件内部的inputRef无关。通过使用这个ref属性,我们可以将子组件中的事件暴露给父组件。
TypeScript
import React, { FC, forwardRef, useImperativeHandle, useRef } from 'react';
export type ChildType = {
focus: () => void;
getInputValue: () => Promise<any>;
};
const UseImperativeHandleChildDemo: FC<{
placeholder?: string;
onchange: (value: string) => void;
ref: React.Ref<ChildType>;
}> = forwardRef(({ placeholder, onchange }, ref) => {
// 这里是定义该组件内的input框的ref属性,和上面的ref有点不一样的是,上面的ref是由父组件传进来,获取子组件(本组件)内部的方法。
const inputRef: React.MutableRefObject<HTMLInputElement | null> = useRef(null);
useImperativeHandle(
ref,
() => {
const focus = () => {
return inputRef.current?.focus?.();
};
const getInputValue = () => {
return new Promise<any>((resolve, reject) => {
if (inputRef.current?.value) {
resolve(inputRef.current?.value);
} else {
reject('您没有输入任何值');
}
});
};
return { focus, getInputValue };
},
[]
);
return (
<input placeholder={placeholder} ref={inputRef} onChange={(e) => onchange(e.target.value)} />
);
});
export default UseImperativeHandleChildDemo;
4.2、父组件 👇👇
父组件中使用到了一个ChildType类型是由上面的子组件暴露出来的,定义这个类型是让我们更方便的获取到子组件通过ref暴露出来的方法有那些。
TypeScript
import React, { useRef } from 'react';
import UseImperativeHandleChildDemo, { ChildType } from './UseImperativeHandleChildDemo';
function UseImperativeHandleDemo() {
const inputRef = useRef<ChildType>(null);
// 通过传递给子组件的ref实现子组件input框聚焦
const handleClick = () => {
inputRef.current?.focus();
};
const getInputValue = () => {
inputRef.current
?.getInputValue()
.then((value) => {
console.log('👉👉👉-----------------点击按钮获取到的值', value);
})
.catch((e) => {
console.log('👉👉👉-----------------', e);
});
};
return (
<div className="App">
<UseImperativeHandleChildDemo
placeholder="请输入值"
ref={inputRef}
onchange={(value) => {
console.log('👉👉👉-----------------chang事件', value);
}}
/>
<button onClick={handleClick}>子组件input框聚焦</button>
<button onClick={getInputValue}>获取子组件input的值</button>
</div>
);
}
export default UseImperativeHandleDemo;
4.3、使用组件 👇👇
通过执行这些代码以后,在浏览器控制台你就能观察到相应的信息
TypeScript
import React from 'react';
import UseImperativeHandleDemo from './Demo/UseImperativeHandleDemo';
function App() {
return (
<div className="App">
<UseImperativeHandleDemo />
</div>
);
}
export default App;
五、总结 💪💪
useImperativeHandle和forwardRef都是React Hooks的一部分,它们的作用和重要性如下:
useImperativeHandle是一个用于暴露自定义ref属性和自定义方法的钩子函数。它使得父组件可以通过ref访问子组件中定义的方法和属性,从而实现对子组件的精细控制。也就是说,父组件可以使用子组件的方法或者控制子组件。当使用useImperativeHandle时,需要子组件中的第二个参数(ref)当作useImperativeHandle的第一个参数。
forwardRef是一个高阶组件,用于将引用(ref)从父组件转发到子组件。这对于访问子组件的DOM元素非常有用。在父组件中,可以通过使用forwardRef来触发子组件的功能。
总的来说,useImperativeHandle和forwardRef都是React中非常重要的钩子和函数,它们可以帮助开发者更好地控制组件的行为和属性,提高代码的可读性和可维护性。
👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇