返回

学习 React(四):理解 ref

前端

ref 的基本概念

在React中,ref 属性允许你获取一个DOM元素或组件的引用。这个引用可以用来操作DOM元素或组件,比如获取它的属性、调用它的方法,或直接修改它。ref属性的值根据节点的类型而有所不同:

  • 当 ref 属性用于HTML元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素
  • 当 ref 属性用于自定义类组件时,ref 接收组件的实例
  • 当 ref 属性用于函数组件时,ref 接收一个包含组件 DOM 元素的回调函数

使用 ref 获取 DOM 元素

获取 DOM 元素最简单的方法是使用 React.createRef() 方法。这个方法返回一个 ref 对象,该对象具有一个 current 属性,该属性指向 DOM 元素。

import React, { useRef } from "react";

const MyComponent = () => {
  const inputRef = useRef();

  return (
    <input type="text" ref={inputRef} />
  );
};

在这个示例中,我们使用 useRef() 方法创建了一个 ref 对象 inputRef。然后,我们将 inputRef 传递给 input 元素的 ref 属性。这样,我们就可以在组件中使用 inputRef.current 来访问 DOM 元素。

import React, { useRef } from "react";

const MyComponent = () => {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <>
      <input type="text" ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </>
  );
};

在自定义组件中使用 ref

在自定义组件中,ref 可以用来访问组件的实例。这可以用来调用组件的方法,获取组件的属性,或直接修改组件。

import React, { useRef } from "react";

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  render() {
    return (
      <div ref={this.myRef}>
        <h1>Hello World</h1>
      </div>
    );
  }
}

在这个示例中,我们在 MyComponent 类中创建了一个 ref 对象 myRef。然后,我们将 myRef 传递给 div 元素的 ref 属性。这样,我们就可以在组件中使用 this.myRef.current 来访问组件的实例。

import React, { useRef } from "react";

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  focus() {
    this.myRef.current.focus();
  }

  render() {
    return (
      <>
        <div ref={this.myRef}>
          <h1>Hello World</h1>
        </div>
        <button onClick={() => this.focus()}>Focus</button>
      </>
    );
  }
}

ref 在组件生命周期方法和父子组件通信中的作用

ref 可以在组件的生命周期方法和父子组件通信中发挥重要作用。例如,ref 可以用来在组件挂载和卸载时执行特定的操作。

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

const MyComponent = () => {
  const inputRef = useRef();

  useEffect(() => {
    inputRef.current.focus();

    // 在组件卸载时清理 ref
    return () => {
      inputRef.current = null;
    };
  }, []);

  return (
    <input type="text" ref={inputRef} />
  );
};

在这个示例中,我们在组件挂载时使用 useEffect() 方法将焦点设置到输入框。我们在组件卸载时使用 return 语句来清理 ref。

ref 还可以在父子组件通信中发挥重要作用。例如,父组件可以使用 ref 来访问子组件的实例,然后调用子组件的方法或获取子组件的属性。

import React, { useRef } from "react";

const ParentComponent = () => {
  const childRef = useRef();

  const focusChildInput = () => {
    childRef.current.focus();
  };

  return (
    <>
      <ChildComponent ref={childRef} />
      <button onClick={focusChildInput}>Focus Child Input</button>
    </>
  );
};

const ChildComponent = (props) => {
  return (
    <input type="text" ref={props.ref} />
  );
};

在这个示例中,父组件 ParentComponent 使用 ref 属性来访问子组件 ChildComponent 的实例。然后,父组件可以使用 childRef.current.focus() 来聚焦子组件的输入框。

总结

ref 是一个非常强大的工具,可以用来操作DOM元素和自定义组件。ref 可以用来获取DOM元素,在自定义组件中访问组件实例,并在组件生命周期方法和父子组件通信中发挥重要作用。通过熟练掌握ref的使用,你可以编写出更加高效和可控的React应用程序。