Three major attributes of React components: refs

1. Understand

Refs are a mechanism in React for accessing DOM elements within a component or other React component instances. They provide a way for you to directly manipulate and access DOM elements in React, or communicate between React components.

use:

  • Focus management, text selection, media playback;
  • Force trigger animation;
  • Inherit third-party DOM libraries;

2. What are the ways to create refs?

2.1. String Refs (not recommended)

String Refs are a way to create Refs in React, but starting from React 16.3, it is no longer officially recommended because it has some potential problems, such as performance issues and maintainability issues. However, for the sake of completeness, I will show how to use string Refs, but please use them with caution.

In String Refs, you assign the Ref as a string, usually in componentDidMount, which you can then access via this.refs to get the reference.

Here is an example:

import React, {
    
     Component } from 'react';

class MyComponent extends Component {
    
    
  componentDidMount() {
    
    
    // 分配Ref为字符串
    this.refs.myRefElement.focus();
  }

  render() {
    
    
    return (
      <div>
        <input ref="myRefElement" /> {
    
    /* 分配Ref为字符串 */}
      </div>
    );
  }
}

export default MyComponent;

In the above example, we use the string "myRefElement" to assign the Ref to the input element and then in componentDidMount Access the element via this.refs.myRefElement and set focus to it.

Although string Refs were valid in the past, they are no longer officially recommended because they have issues with:

  1. Performance issue: String Refs need to maintain an additional mapping table internally in React in order to find Ref by string name. This can cause performance issues, especially in components with a large number of Refs.

  2. Maintainability: When working with string Refs, they are difficult to statically analyze and inspect, so it is prone to typos or Refs that cannot be found.

Therefore, it is recommended to use React.createRef() or useRef hooks to create Refs in modern React applications to improve performance and maintainability.

2.2. Callback Refs

Callback Refs are a way to create Refs in React components, which can be used to access DOM elements or other component instances. This method was the main way to create Refs before React 16.3. Although after React 16.3, it is officially recommended to use React.createRef() or useRef hooks to create Refs, but callback Refs Still a valid approach.

Here is a detailed description of how to use callback Refs:

  1. Create Refs: In the component, first define a variable to save the Ref object, usually initialized to null in the constructor.

    class MyComponent extends React.Component {
          
          
      constructor(props) {
          
          
        super(props);
        this.myRef = null;
      }
    }
    
  2. Assign Refs to elements or components: On the DOM element or component that needs to be referenced, use the ref attribute to set the Ref variable to the callback function .

    setMyRef = (element) => {
          
          
      this.myRef = element;
    }
    
    render() {
          
          
      return (
        <div>
          <input ref={
          
          this.setMyRef} />
        </div>
      );
    }
    

    Through this callback function,this.myRef will reference the DOM element or component instance associated with it.

  3. Access Refs: Where you need to access Refs, you can use this.myRef to get the referenced element or component.

    componentDidMount() {
          
          
      if (this.myRef) {
          
          
        this.myRef.focus(); // 通过 Ref 聚焦到输入框
      }
    }
    

The advantage of callback Refs is that they are valid in earlier React versions and work well for accessing instances of DOM elements or subcomponents. However, with the update of React version, it is officially recommended to use React.createRef() or useRef hooks because they have more advantages in performance and maintainability. When it comes to creating Refs in modern React projects, it's often a better option to use React.createRef() (class components) or useRef hooks (functional components).

2.3. React.createRef() (recommended)

In React 16.3 and later, you can create Refs using the built-in React.createRef() method. This is an officially recommended method.

Creating Refs using React.createRef() is easy. Here's a specific example:

import React from 'react';

class MyComponent extends React.Component {
    
    
  constructor(props) {
    
    
    super(props);
    this.myRef = React.createRef(); // 创建Ref对象
  }

  componentDidMount() {
    
    
    // 在组件渲染后,可以访问DOM元素
    this.myRef.current.focus(); // 聚焦到DOM元素
  }

  render() {
    
    
    return (
      <div>
        <input ref={
    
    this.myRef} /> {
    
    /* 将Ref分配给input元素 */}
        <button onClick={
    
    this.focusInput}>Focus Input</button>
      </div>
    );
  }

  focusInput = () => {
    
    
    // 在事件处理程序中访问Ref
    this.myRef.current.focus();
  };
}

export default MyComponent;

In the above example, we first create a Ref object using React.createRef() in the constructor, and then use input on the element The > again. . We also use Ref in a button's click event handler to focus the focus on to access the DOM element and focus on lifecycle method, we use ref attribute assigns this Ref to the DOM element. In the componentDidMountthis.myRef.currentinputinput

This is the general process of creating and accessing Refs using React.createRef() . This method is usually used to access and manipulate DOM elements, or reference instances of subcomponents.

2.4. Through React Hook (functional component)

Creating Refs in functional components is also very simple using React Hook (useRef hook). Here's a specific example:

import React, {
    
     useRef, useEffect } from 'react';

function MyComponent() {
    
    
  const myRef = useRef(null); // 创建Ref对象

  useEffect(() => {
    
    
    // 在组件渲染后,可以访问DOM元素
    myRef.current.focus(); // 聚焦到DOM元素
  }, []);

  const focusInput = () => {
    
    
    // 在事件处理程序中访问Ref
    myRef.current.focus();
  };

  return (
    <div>
      <input ref={
    
    myRef} /> {
    
    /* 将Ref分配给input元素 */}
      <button onClick={
    
    focusInput}>Focus Input</button>
    </div>
  );
}

export default MyComponent;

In the above example, we first create a Ref object using useRef(null). The argument to useRef() is an initial value, usually set to null since it doesn't care about the actual value on initial rendering.

Then, we use the useEffect hook to simulate the componentDidMount lifecycle method, where we use myRef.current to access the DOM element and Focus oninput. useEffect Accepts the second parameter, a dependency array, here an empty array, indicating that this effect will only be executed during the initial rendering of the component.

Finally, we use Ref again in a button's click event handler to focus the focus oninput.

Use useRef hooks to conveniently create and access Refs in functional components, as well as perform Refs-related operations without using class components. This method is available in React 16.8 and later versions.

3. Example

3.1. Focus management

Here is a simple React example that demonstrates how to use Refs to manage focus by moving focus from one input box to another. This example includes a button that, when clicked, moves focus from one input box to another.

import React, {
    
     Component } from 'react';

class FocusManagementExample extends Component {
    
    
  constructor(props) {
    
    
    super(props);
    this.inputRef1 = React.createRef(); // 创建 Ref for Input 1
    this.inputRef2 = React.createRef(); // 创建 Ref for Input 2
  }

  moveFocus = () => {
    
    
    this.inputRef2.current.focus(); // 移动焦点到 Input 2
  };

  render() {
    
    
    return (
      <div>
        <input ref={
    
    this.inputRef1} placeholder="Input 1" />
        <input ref={
    
    this.inputRef2} placeholder="Input 2" />
        <button onClick={
    
    this.moveFocus}>Move Focus to Input 2</button>
      </div>
    );
  }
}

export default FocusManagementExample;

In this example, we first create two Refs, this.inputRef1 and this.inputRef2, which reference the two input boxes respectively. Then, in the moveFocus method, we use this.inputRef2.current.focus() to move focus to the second input box. When the button is clicked, the moveFocus method is called and the focus will move from input box 1 to input box 2.

3.2. Text selection

Below is a simple React example that demonstrates how to use Refs to implement text selection functionality. In this example, there is a text input box and a button that, when clicked, selects the text in the text input box.

import React, {
    
     Component } from 'react';

class TextSelectionExample extends Component {
    
    
  constructor(props) {
    
    
    super(props);
    this.inputRef = React.createRef(); // 创建 Ref for the text input
  }

  selectText = () => {
    
    
    if (this.inputRef.current) {
    
    
      this.inputRef.current.select(); // 选择文本输入框中的文本
    }
  };

  render() {
    
    
    return (
      <div>
        <input ref={
    
    this.inputRef} placeholder="Type some text" />
        <button onClick={
    
    this.selectText}>Select Text</button>
      </div>
    );
  }
}

export default TextSelectionExample;

In this example, we first create a Ref this.inputRef and assign it to the input box. Then, we define the selectText method, which uses this.inputRef.current.select() to select the text in the text input box. When the button is clicked, the selectText method is called and the text of the text input box will be selected.

3.3. Media playback

Here is an example of using React to create a simple media player. This example includes a play/pause button, an audio element, and some state management to control the playback state.

import React, {
    
     Component } from 'react';

class MediaPlayerExample extends Component {
    
    
  constructor(props) {
    
    
    super(props);
    this.audioRef = React.createRef(); // 创建 Ref for the audio element
    this.state = {
    
    
      isPlaying: false,
    };
  }

  togglePlay = () => {
    
    
    const audio = this.audioRef.current;

    if (this.state.isPlaying) {
    
    
      audio.pause();
    } else {
    
    
      audio.play();
    }

    this.setState({
    
     isPlaying: !this.state.isPlaying });
  };

  render() {
    
    
    return (
      <div>
        <audio ref={
    
    this.audioRef} controls>
          <source src="your-audio-file.mp3" type="audio/mpeg" />
          Your browser does not support the audio element.
        </audio>
        <button onClick={
    
    this.togglePlay}>
          {
    
    this.state.isPlaying ? 'Pause' : 'Play'}
        </button>
      </div>
    );
  }
}

export default MediaPlayerExample;

In this example, we first create a Ref this.audioRef and assign it to the audio element. We then define a togglePlay method that plays or pauses the audio based on the current playback state (isPlaying) and then updates the state to reflect the new playback state.

<audio>The element is used to play audio files, with controls to control playback. You can specify the URL of the audio file in the attribute of the <source> element. src

The button element allows the user to click to toggle the play/pause state and displays the current state on the button.

This is a simple media player example, you can extend it to add more functions according to your actual needs, such as volume control, skip, loop, etc.

3.4. Forced trigger animation

In React, you can use ref to access a component or DOM element to force an animation when needed. Here's a simple example of how to force a CSS animation using React and ref:

import React, {
    
     Component } from 'react';

class AnimationExample extends Component {
    
    
  constructor(props) {
    
    
    super(props);
    this.animationBoxRef = React.createRef(); // 创建 Ref for the animated box
  }

  startAnimation = () => {
    
    
    const box = this.animationBoxRef.current;

    // 添加 CSS 类以触发动画
    box.classList.add('animate');

    // 在动画完成后,移除 CSS 类以重置动画
    box.addEventListener('animationend', () => {
    
    
      box.classList.remove('animate');
    });
  };

  render() {
    
    
    return (
      <div>
        <div
          ref={
    
    this.animationBoxRef}
          className="box"
        ></div>
        <button onClick={
    
    this.startAnimation}>Start Animation</button>
      </div>
    );
  }
}

export default AnimationExample;

In this example, we first create a Ref this.animationBoxRef and assign it to a div element that div element represents the target of animation. We then defined the startAnimation method, which uses classList to add a CSS class animate to div element to trigger the animation.

After the animation ends, we useaddEventListener to listen to the animationend event and remove the CSS class in the event handleranimate to reset the animation state.

The button element allows users to click to trigger animations. You can define corresponding animation effects in CSS, for example, through the @keyframes rule to define the details of the animation.

3.5. Inherit third-party DOM libraries

Inheriting a third-party DOM library usually requires using ref in React to access and operate DOM elements in the third-party library. The following is an example that demonstrates how to inherit a third-party DOM library in React (here, using the D3.js library as an example):

First, make sure the D3.js library has been introduced into your project. You can use npm or add it to your project through the <script> tag.

import React, {
    
     Component } from 'react';
import * as d3 from 'd3'; // 引入 D3.js

class D3IntegrationExample extends Component {
    
    
  constructor(props) {
    
    
    super(props);
    this.svgRef = React.createRef(); // 创建 Ref for the SVG element
  }

  componentDidMount() {
    
    
    // 在组件挂载后,初始化 D3.js 操作
    const svg = d3.select(this.svgRef.current);

    // 在 SVG 中添加一个矩形
    svg
      .append('rect')
      .attr('x', 10)
      .attr('y', 10)
      .attr('width', 100)
      .attr('height', 50)
      .style('fill', 'blue');
  }

  render() {
    
    
    return (
      <div>
        <svg ref={
    
    this.svgRef} width={
    
    200} height={
    
    100}></svg>
      </div>
    );
  }
}

export default D3IntegrationExample;

In this example, we first introduce the D3.js library. We then create a Ref this.svgRef and assign it to a <svg> element, which will be used to draw the D3.js graph.

In thecomponentDidMount lifecycle method, we use the d3.select method of D3.js to select the <svg> element, And add a blue rectangle inside it. You can perform more complex operations based on the D3.js documentation and needs.

This example demonstrates how to extend third-party DOM libraries in React, specifically D3.js. You can inherit other third-party libraries based on your project needs, and then use ref to access and operate their DOM elements.

Reference address

chatgpt

https://zhuanlan.zhihu.com/p/549934728

Guess you like

Origin blog.csdn.net/weixin_35691921/article/details/134134998
Recommended