Question origin

After wrapping the child component with ANTD’s form.create (), the parent component wants to get the instance of the child component through the wrappedComponentRef of the wrapped component. But because the subcomponent is a function Component with no instance, you cannot use the wrappedComponentRef attribute on the subcomponent. Antd also wraps the ref property to return an instance of the subcomponent instead.

The solution

Use the callback function to get the this of the child component, or to convert the functional component to a class

  • A child component of the class is 🌰 :
class CollectionCreateForm extends React.Component {
    render() {
      const { visible } = this.props;
      return (
        <Modal visible={visible}>
          <span> hello </span>
        </Modal>); }}export default class App extends React.Component {
  state = {
    visible: false}; showModal =(a)= > {
    this.setState({ visible: true });
  };
  saveFormRef = formRef= > {
    this.formRef = formRef;
    console.log(this.formRef, "I want to export.")}; render() {return (
      <div>
        <Button type="primary" onClick={this.showModal}>
          New Collection
        </Button>
        <CollectionCreateForm
          ref = {this.saveFormRef}
          visible = {this.state.visible}
        />
      </div>); }}Copy the code

  • One child Component is function Component 🌰 :
// Change the subcomponent
function CollectionCreateForm(props){
  const { visible } = props;
    return(
        <Modal visible={visible}>
          <span> hello </span>
        </Modal>)}Copy the code

Note that we can’t get the child component instance, but we can get the DOM refs in the child component.

Anyway, you can use the ref attribute inside a function component as long as it points to a DOM element or a class component, right

Parent component ref pass

So what do you do if you want to retrieve the DOM refs from a functional component in its parent?

  1. Ref to forwardUse:React.forwardRefFunction wrappingfunction component

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()

React.forwardRef((prop,ref) = >{function component})
Copy the code

eg:

import React, {forwardRef} from 'react';

function ThisWontWork() {
  return <button>Text</button>;
}

const ThisWillWork = forwardRef((props, ref) = > { // React passes ref to the callback function (props, ref) =>... , as its second parameter.
  return <button ref={ref}>Text</button>;// Deliver the ref parameter and assign it to button's JSX property
});

function App() {
const childRef = React.createRef(); 
console.log(childRef) // {current:<button></button>}
  return (
    <Tippy content="Tooltip">// Get the ref of the child component<ThisWillWork ref={childRef}/>
    </Tippy>
  );
}
Copy the code
  1. Using custom attributes, use the REF attribute inside a function component as long as it points to a DOM element or class component.
function CustomTextInput(props) {
  return<div> <input ref={props. InputRef} /> } class Parent extends React.Component { constructor(props) { super(props); this.inputElement = React.createRef(); } render() { return ( <CustomTextInput inputRef={this.inputElement} /> ); }}Copy the code

3. Wrap a function and pass it to a subcomponent to get this or refs from an element without using a callback:

<childCom childRef={refs =>{this.refs = refs}}>... </childCom> <div ref={props. ChildRef}>hello</div> </childCom>Copy the code