一、类方法获取子组件节点
如果是class类,存在实例,可以通过 React.createRef() 挂载到节点或者组件上,然后通过 this 获取到该节点或组件。
class RefTest extends React.Component{
constructor(props){
super(props);
this.myRef=React.createRef();
}
componentDidMount(){
console.log(this.myRef.current);
}
render(){
return <input ref={this.myRef}/>
}
}
二、React-hooks获取子组件节点和方法
在子组件是函数组件的时候,因为函数组件没有实例,所以在正常情况下, ref 是不能挂载函数组件上的。那么此时,我们通过 useImperativeHandle
和 forwardRef
配合就能达到效果。
useImperativeHandle
useImperativeHandle:可以配合 forwardRef 自定义暴露给父组件的实例值。
useImperativeHandle为我们提供了一个类似实例的东西,它帮助我们通过useImperativeHandle 的第二个参数,将所返回的对象的内容挂载到父组件的 ref.current 上.
useImperativeHandle 接收三个参数:
① 第一个参数 ref:接收 forWardRef 传递过来的 ref。 ② 第二个参数 createHandle:处理函数,返回值作为暴露给父组件的 ref 对象 ③ 第三个参数 deps:依赖项 deps,依赖项更改形成新的 ref 对象。 forwardRef 会创建一个 React 组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。
注意:Form.create()嵌套的话,父组件需要通过wrappedComponentRef来获取子组件节点和方法
子组件
import React, { useState,forwardRef,useImperativeHandle } from "react";
const ChildContainer = (props,onRef) => {
let { getFieldDecorator,validateFields } = props.form;
let [userName,setUserName] = useState();
const submit = ()=>{
}
// 暴露给父组件的属性
useImperativeHandle(onRef, () => {
return {
submit,
setUserName,
...props.form
}
});
return (
<div className="childContainer">
</div>
)
}
export default Form.create()(forwardRef(ChildContainer));
父组件(子组件Form.create()嵌套)
import React, { useState,useRef } from "react";
import ChildContainer from "./components/ChildContainer";
const TestRef = (props) => {
const collectRef = useRef(null);
return (
<div className="testRef">
<ChildContainer wrappedComponentRef={collectRef}></ChildContainer>
</div>
)
}
export default Form.create()(TestRef);
父组件(子组件不是 Form.create()嵌套)
import React, { useState,useRef } from "react";
import ChildContainer from "./components/ChildContainer";
const TestRef = (props) => {
const collectRef = useRef(null);
return (
<div className="testRef">
<ChildContainer ref={collectRef}></ChildContainer>
</div>
)
}
export default Form.create()(TestRef);