React 中的引用是什么?

IT技术 reactjs
2021-04-25 15:34:08

我无法理解 React 中的 ref 是什么。我知道这是一个回调函数,你把它放在渲染函数中,但除此之外我无法理解它是什么以及它的目的是什么。

4个回答

Refs 是您获取已创建组件的句柄的一种方式。

IE。

<Text ref={(component)=>{this.textComponent = component}} > Here is some Text</Text>

然后在您的代码中,您可以通过执行以下操作访问您的文本:

this.textComponent

这将使您能够以面向对象的方式调用组件上的函数。

我只想指出 React/React-Native 使用声明式编程范式,其中数据和“控制”通过自上而下的属性传递进行管理。而在命令式风格中,您处理对象和指针并传递它们以便调用它们上的函数。在这种情况下,Refs 是一个逃生舱口,它允许您获得一个声明的组件,以便您可以以命令式风格调用它们上的函数。

参考 React 官方文档:https : //reactjs.org/docs/refs-and-the-dom.html

React 有典型的处理孩子的方式。props以自上而下的方式使用。并且要修改孩子,您必须使用新props重新渲染。但是在某些情况下,您希望在此典型流程之外修改/处理子项。在这些情况下,您使用 refs。

Ref 是一个接受回调的属性,每当安装或卸载组件时都会调用此回调。可以将 Refs 添加到 dom 元素或组件。例子:

return (
  <div>
   <input
     type="text"
     // ref to a dom element
     ref={(input) => { this.textInput = input; }} />
  </div>
);

return (
  <MyComponent 
    // ref to a MyComponent(child component)
    ref={(component) => { this.childComponent = component; }}
    {...props}
  />
);

每当安装组件时,都会使用 dom 元素或子组件实例调用 ref 回调。每当组件卸载时,它都会用null.

现在您可以使用this.textInputorthis.childComponent并在其上调用其不同的可用方法。


Refs 只能提供给 DOM 元素或类组件。它们不适用于功能组件。例子:

function MyFunctionalComponent(props) {
  return <input type="text" />;
}

return (
  <MyFunctionalComponent 
    // This won't work
    ref={(component) => { this.childComponent = component; }}
    {...props}
  />
);

仅在绝对必要时才应使用 Refs,因为它们使您可以直接访问 DOM 中的元素/组件。

Refs 是一种在 DOM 元素或类组件实例上设置变量的方法。

有两种类型的引用:回调引用和对象引用。

对象引用

使用useRef()创建对象引用React.createRef()

要使用它们(一个带有引用 DOM 元素的函数组件的示例):

  1. 声明一个“容器”变量(您将在下一步中指向一个 DOM 元素)并将其设置为等于useRef(). 这是您的“参考对象”。

  2. ref向 DOM 元素添加属性。将其设置为等于您的ref对象。

  3. 现在这个ref对象代表了你指向它的 DOM 元素,可以用来访问它的方法和属性。

    function InputField() {
        const refForInput = useRef(); // 1. initializing `refForInput` as a reference object.
        return (
            <div>
                <input type='text' ref={refForInput} /> //2. passing it to the input element as its ref
                <button onClick={() => refForInput.current.focus()}>Click to focus the input field</button> // 3. now, calling `refForInput` will refer to the DOM <input> element, and you can access its `focus()` method.
            </div>
        )
    }
    

如果使用类组件,过程类似;有关详细信息,请参阅React 文档

回调引用

回调引用功能类似,但允许更细粒度的控制。

要创建回调引用,您可以类似地ref向 DOM 元素添加一个属性,但不是传入ref对象,而是传入回调。这个回调接收元素本身作为回调的参数;然后,您可以将其设置为等于现有值(this.something在类中;在函数组件中已声明的变量。)

这是来自 Avid Programmer 优秀示例的示例的带注释的 vversion;有关类的示例,请参阅他的回答。

    function CustomForm({handleSubmit}) {
        let inputElement;
        return (
            <form onSubmit={() => handleSubmit(inputElement.value)}> // 2. Now, this refers to the `value` of the `<input>` element just below.
                <input
                type='text'
                ref={(input) => inputElement = input} // 1. so, here, `input` in the callback refers to the DOM element. Now, when the component mounts, `inputElement` will *reference* this DOM <input> element.
                />
                <button type='submit'>Submit</button>
            </form>
        )
    }

请注意,将null在组件卸载时调用回调

它们为什么有用?

它们不应该经常使用;它们是逃生舱口。它们允许您访问focus()在 React 组件上可能不可用的实际 html 元素上可用的API 方法(是一个常见示例)。如果这看起来令人困惑,请记住,例如,React 按钮组件与 html 按钮组件不同。您可以调用focus()html 按钮元素,但不能调用React 按钮元素。

Refs 是一个逃生舱,它允许您直接访问 DOM 元素或组件的实例。为了使用它们,您向组件添加一个 ref 属性,该属性的值是一个回调函数,它将接收底层 DOM 元素或组件的已安装实例作为其第一个参数。

class UnControlledForm extends Component {
  handleSubmit = () => {
    console.log("Input Value: ", this.input.value)
  }
  render () {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type='text'
          ref={(input) => this.input = input} />
        <button type='submit'>Submit</button>
      </form>
    )
  }
}

通过利用 JavaScript 中的闭包,refs 还可以与功能组件一起使用。

function CustomForm ({handleSubmit}) {
  let inputElement
  return (
    <form onSubmit={() => handleSubmit(inputElement.value)}>
      <input
        type='text'
        ref={(input) => inputElement = input} />
      <button type='submit'>Submit</button>
    </form>
  )
}

(“闭包”只是引用在函数外声明的变量的一种奇特方式 - 在这种情况下,inputElement- 在您的函数内,在这种情况下ref={(input) => inputElement = input}。)