A class component case

  • 1, define the parent component (use ref directly)

    export default class UserRef1 extends Component {
      constructor(props) {
        super(props);
        this.child = React.createRef();
      }
      focus = () = > {
        console.log(this.child.current.inputRef.current.value);
        this.child.current.inputRef.current.focus();
      }
      render() {
        return (
          <div>
            <Child ref={this.child} />
            <button onClick={this.focus}>Get focus</button>
          </div>)}}Copy the code
  • 2. In sub-components

    class Child extends Component {
      constructor(props) {
        super(props);
        this.state = {
          name: 'ha ha'
        }
        this.inputRef = React.createRef();
      }
      render() {
        return (
          <input type="text" value={this.state.name} onChange={(e)= > this.setState(e.target.value)} ref={this.inputRef} />)}}Copy the code

2. Function components

To obtain the data of a child component in a function component, there are two steps: 1. Pass the ref to the child component,2. The subcomponents need to be wrapped using the forwardRef

  • 1. Parent component

    export default() = > {const parentRef = useRef();
      function focusHander() {
        console.log(parentRef);
        parentRef.current.focus();
        parentRef.current.value = 'ha ha';
      }
      return (
        <>
          <ForwardChild ref={parentRef} />
          <button onClick={focusHander}>Get focus</button>
        </>)}Copy the code
  • 2. In sub-components

    function Child(props, parentRef) {
      console.log(props);
      return (
        <>
          <input type="text" ref={parentRef} />
        </>)}/** * use the forwardRef to pass the ref directly into */
    let ForwardChild = forwardRef(Child);
    Copy the code

Three, optimize

All of the above methods expose all of the data in the component, sometimes we want to expose only part of the data

  • 1, child component code

    import React, { useState, useRef, useImperativeHandle, forwardRef } from 'react'
    
    function Child(props, parentRef) {
      const inputRef = useRef();
      useImperativeHandle(parentRef, () = > {
        // Return the value returned by the parent component
        return {
          focus(){ inputRef.current.focus(); }}})return (
        <>
          <p>{props.name}</p>
          <input type="text" ref={inputRef} />
        </>)}let ForwardChidl = forwardRef(Child);
    Copy the code
  • 2, the parent component code

    export default() = > {const parentRef = useRef();
    
      const focusHandler = () = > {
        parentRef.current.focus();
      }
      return (
        <>
          <ForwardChidl ref={parentRef} name={'Hello '} />
          <button onClick={focusHandler}>Get focus</button>
        </>)}Copy the code