【问题标题】:What are refs in React?React 中的 ref 是什么?
【发布时间】:2017-10-19 00:00:37
【问题描述】:

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

【问题讨论】:

    标签: reactjs


    【解决方案1】:

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

    即。

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

    然后在您的代码中,您可以通过以下方式访问您的文本:

    this.textComponent
    

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

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

    请参阅官方 React 文档以获取 refs: https://reactjs.org/docs/refs-and-the-dom.html

    【讨论】:

    • 它也适用于像&lt;input&gt;这样的“原生”元素,它会反馈给你一个DOMElement,这样你就可以做getBoundingClientRectfocus()这样的事情,这通常是我有过的使用它。
    【解决方案2】:

    React 有典型的处理孩子的方式。它以自上而下的方式使用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.textInputthis.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 的最好的单句 - 太棒了!
    【解决方案3】:

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

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

    对象引用

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

    使用它们(函数组件引用 DOM 元素的示例):

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

    2. 为您的 DOM 元素添加 ref 属性。将其设置为等于您的 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 docs

    回调引用

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

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

    这是来自 Avid Programmer 的优秀示例的示例的注释版本;请参阅他的答案以获取有关课程的示例。

        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 调用。

    它们为什么有用?

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

    【讨论】:

    • 那么你说的“逃生舱”是什么意思?我不认为你理解 ref,因为你没有提到它与 react 组件的生命周期相关的概念。
    【解决方案4】:

    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) =&gt; inputElement = input}。)

    【讨论】:

    • 但你没有解释“逃生舱”是什么意思。
    • inputElement 是在CustomForm 内部声明的,而不是在其外部。
    猜你喜欢
    • 2020-02-11
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 2020-09-25
    • 1970-01-01
    相关资源
    最近更新 更多