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