useImperativeHandle介绍:
useImperativeHandle(ref, createHandle, [deps])
useImperativeHandle
:https://zh-hans.reactjs.org/docs/hooks-reference.html#useimperativehandle
forwardRef
:https://zh-hans.reactjs.org/docs/react-api.html#reactforwardref
文章
useImperativeHandle 可以让你在使用 ref 时自定义
暴露给父组件
的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。
子组件内
useImperativeHandle 应当与 forwardRef 一起使用。
- ref:定义 current 对象的 ref createHandle:一个函数,返回值是一个对象,即这个 ref 的 current。
- 对象 [deps]:即依赖列表,当监听的依赖发生变化,useImperativeHandle 才会重新将子组件的实例属性输出到父组件。
- ref 的 current 属性上,如果为空数组,则不会重新输出。
父组件
import React, { forwardRef, useImperativeHandle, } from 'react';
const Parent =(props, ref)=> { //必须Parent =(props, ref),不能Parent =(ref),props顺序
const inputRef = useRef();
const treeReq=()=>{
//调用子组件方法
inputRef.current.setfocus('传参')
}
return (
<div>
<button type="button" onClick={treeReq}>
查询
</button>
<FancyInput ref={inputRef} />
</div>
)
}
export default Parent;
子组件
- 函数的第一个参数为父组件传递的 props,第二给参数为父组件传递的 ref,其目的就是希望可以在封装组件时,外层组件可以通过 ref 直接控制内层组件或元素的行为。
- useImperativeHandle 的第一个参数是定义 current 对象的 ref,第二个参数是一个函数,返回值是一个对象,即这个 ref 的 current 对象,这样可以像上面的案例一样,通过自定义父组件的 ref 来使用子组件 ref 的某些方法。
const FancyInput=(props, ref)=> {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
setfocus: (data) => {
console.log('父组件调用子组件方法传参',data);
setfocus();
}
}));
const setfocus=()=>{
console.log('函数');
}
}
export default forwardRef(FancyInput);
重要:
useImperativeHandle 和 React.forwardRef 必须是配合使用的。
通过 useImperativeHandle 将子组件的实例属性输出到父组件,而子组件内部通过 ref 更改 current 对象后,组件不会重新渲染,需要改变 useState 设置的状态才能更改。
版权声明:本文为Z_Wonderful原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。