React Ref Multi-scenario tutorial

Since Act 16.8, we have been continuously embracing Hook development, and the use of REF is particularly important when componentized development has become indispensable to us.

But class development is still used by most people, so let’s look at a few scenarios where ref is used.

There are several scenarios:

  • Parent component: class, child component: class
  • Parent component: hook, child component: hook
  • Parent component: class, child component: hook
  • Parent: hook, child: class

The above scenario if indvaIs problematic for use in, and is analyzed for each scenario

Here are a few scenarios: how to call methods and data inside child components from parent components.

Parent component: class, child component: class

1. Child components are not useddvasituation

The child component does not need any extra operations, just write the parent component.

. import { Button }from 'antd-mobile';
import { NoDvaSon } from './components'; // Do not use a dVA subcomponent

@connect(({ classclass }) = > ({ classclass }))
class ClassclassPage extends Component {
  noDvaChild: any;

  getSonEvent = (a)= > {
    this.noDvaChild.noDvaSonEvent(); // Call the child component's methods here
    console.log(this.noDvaChild.state); // Get the state value of the child component
  };

  render() {
    return (
      <div>
        <Button onClick={this.getSonEvent}>Invoke methods of child components</Button>
        <NoDvaSon
          ref={(e)= >{ this.noDvaChild = e; }} / ></div>
    );
  }
}
export default ClassclassPage;
Copy the code

2. Use of sub-componentsdvasituation

The parent component is written in the same way as the parent component, except that the child component is added with DVA. When the page is saved and opened, the browser Console will display the following warning.

When we click the parent component’s button to invoke the child component’s methods and data, an error is reported.

Next we modify the code for the child component:

Modify the connect field:

const mapDispatchToProps = (dispatch, ownProps) = > {
  return { dispatch };
};

@connect(({ classclass }) = > ({ classclass }), mapDispatchToProps, null, { forwardRef: true }) // The new React-redux version is supported
@connect(({ classclass }) = > ({ classclass }), mapDispatchToProps, null, { withRef: true }) // Older react-redux versions support this
Copy the code

Just introduce an error from the forwardRef or withRef.

When I wrote the demo, I used withRef, but the browser Console still reported an error and said withRef cannot be used, so I changed it to forwardRef.

Two, parent component: hook, child component: hook

In hook, the use of DVA does not affect the use of ref.

Parent component code:

import React, { FC, useRef } from 'react';
import { Button } from 'antd-mobile';
import { NoDvaSon } from './components';

const HookhookPage: FC = (a)= > {
  const childRef = useRef(); 

  const getSonEvent = (a)= > {
    childRef.current.click(); // Invoke the child component's methods
    console.log(childRef.current.value); // Get the data of the child component
  };

  return (
    <div className={styles.center}>
      <Button onClick={getSonEvent}>Invoke methods of child components</Button>{/* The child component introduces the name cRef, which can be defined arbitrarily */}<NoDvaSon cRef={childRef} /> 
    </div>
  );
}

export default connect(({ hookhook }) => ({ hookhook }))(HookhookPage);
Copy the code

Sub-component code:

import React, { FC, useState, useImperativeHandle } from 'react'; // Import the required useImperativeHandle

interface PageProps {
  cRef: any;
}

const Page: FC<PageProps> = ({ cRef }) = > {
  const [noDvaValue, setNoDvaValue] = useState('noDvaValue');

  /** * here is the key !!!! Note here that the first argument to the useImperativeHandle method is the target element's ref reference */
  useImperativeHandle(cRef, () => ({
    // click is the method exposed to the parent component
    click: (a)= > {
      noDvaSonEvent();
    },
    value: { noDvaValue },
  }));

  const noDvaSonEvent = (a)= > {
    console.log('this is no dva son event');
  };

  return <div>this is no dva son</div>;
};

export default Page;
Copy the code

Parent component: class, child component: hook

In this case directly refer to two, parent component: hook, child component: hook can be. It’s not going to be explained in detail, it’s not going to be shown in the demo.

Parent component: hook, child component: class

For child components of class type, the implementation is similar to the parent component: class and child: class. The code is attached here for your reference

For a child component that does not use DVA, there is no need to add code to the child component, just write it on the parent component:

import React, { FC, useRef } from 'react';
import { HookhookModelState, ConnectProps, connect } from 'alita';
import { Button } from 'antd-mobile';
import { NoDvaClassSon } from './components';

const HookhookPage: FC = ({ hookhook, dispatch }) = > {

  let classChild: NoDvaClassSon | null = null;

  const getclassSonEvent = (a)= > {
    classChild.noDvaSonEvent(); // Invoke the child component's methods
    console.log(classChild.state); // Get the data of the child component
  };

  return (
    <div className={styles.center}>
      <Button onClick={getclassSonEvent}>Calls a method of a class child component</Button>
      <NoDvaClassSon
        ref={(e)= >{// use ref classChild = e; }} / ></div>
  );
};

export default connect(({ hookhook }) => ({ hookhook }))(HookhookPage);
Copy the code

Parent: class + forwardRef: true; parent: class + forwardRef: true

Full demo from here to enter ha, give a star more support

Writing is not easy, little attention to praise ah ~