react-hook useRef 使用(useImperativeHandle)父组件调用子组件函数

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 设置的状态才能更改。

类似例子补充,hook的ref使用


你可能感兴趣的:(#,react,hooks,react.js,javascript,前端)