父组件操作子组件 这是一个老生常谈的问题,在 React16 中 实现 父组件从操作子组件,分以下四步
一、父组件使用 useRef 创建一个 ref 传入子组件
import React, { useRef } from react;
import SonComponent from './SonComponent';
const FatherComponent = (props) => {
const sonComponent = useRef();
return <>
<SonComponent ref={sonComponent} />
</>
}
二、子组件接收ref,此时用到forwardRef,
forwardRef 会创建一个React组件,这个组件能够将其接收的 ref 属性转发到其组件树下的另一个组件中。其目的就是希望可以在封装组件时,外层组件可以通过 ref 直接控制内层组件或元素的行为。
import React, { forwardRef } from 'react';
const SonComponent = forwardRef((props, ref) => {
return <div>我是子组件</div>
})
React.forwardRef 接受渲染函数作为参数。React 将使用 props 和 ref 作为参数来调用此函数。会ref转发给其下的元素中
三、在子组件中将想要给父组件调用的方法通过useImperativeHandle暴漏出来,这里可以初始化 ref 的 current属性
import React, { useImperativeHandle, forwardRef } from 'react';
const SonComponent = forwardRef((props, ref) => {
useImperativeHandle(ref, () => {
return {
hello: () => {
console.log('hello, father!')
}
}
})
return <div>我是子组件</div>
})
export default SonComponent;
四、在父组件中使用, useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数
import React, { useRef } from 'react';
import SonComponent from './SonComponent';
const FatherComponent = (props) => {
const sonComponent = useRef();
const dealWithChildContent = () => {
console.log(sonComponent.current)
// 调用子组件的方法
sonComponent.current.hello();
}
return <>
<SonComponent ref={sonComponent} />
<button onClick={dealWithChildContent}>点击触发</button>
</>
}
export default FatherComponent;