What are refs in React?

前端 未结 4 684
终归单人心
终归单人心 2021-02-09 05:38

I\'m having trouble understanding what refs are in React. I understand that it\'s a callback function and you put it in the render function, but beyond that I can\'t understand

相关标签:
4条回答
  • 2021-02-09 06:03

    React has typical way of handling children. It does it with use of props in a top-down way. And to modify the child you have to re-render with new props. But there are cases where you want to modify/handle child outside of this typical flow. In these cases you use refs.

    Ref is an attribute that takes a callback and this callback is called whenever the component is mounted or unmounted. Refs can be added to both dom elements or components. Example:

    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}
      />
    );
    

    Whenever the component is mounted the ref callback is called with dom element or the child component instance. And whenever the component is unmounted its called with null.

    Now you can use this.textInput or this.childComponent and call its different available methods on it.


    Refs can be given to only either DOM elements or class component. They don't work on functional components. Example:

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

    Refs should be used only when its absolutely necessary as they give you direct access to the element/component in DOM.

    0 讨论(0)
  • 2021-02-09 06:09

    Refs are a way to set a variable at a DOM element or a class component instance.

    There are two types of refs: callback refs, and object refs.

    Object Refs

    Object refs are created using useRef() or React.createRef().

    To use them (an example with a function component referencing a DOM element):

    1. Declare a "container" variable (which you will point at a DOM element in the next step) and set it equal to useRef(). This is your "ref object."

    2. Add a ref attribute to your DOM element. Set it equal to your ref object.

    3. Now this ref object represents the DOM element you pointed it at, and can be used to access its methods and properties.

      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>
          )
      }
      

    The process is similar if using class components; see the React docs for details.

    Callback Refs

    Callback refs function similarly, but allow more fine-grained control.

    To create a callback ref, you similarly add a ref attribute to your DOM element, but instead of passing in a ref object, you pass in a callback. This callback receives the element itself as the argument for the callback; you can then set it equal to an existing value (this.something in a class; an already-declared variable in a function component.)

    Here's an annotated vversion of the example from Avid Programmer's excellent example; see his answer for an example with classes.

        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>
            )
        }
    

    Note that the callback will be called with null when the component unmounts.

    Why are they useful?

    They shouldn't be used often; they're meant as escape hatches. They allow you to access API methods (focus() is a common example) available on the actual html elements that may not be available on the React component. If this seems confusing, remember that a React button component, for example, is not the same as an html button component. You can call focus() on an html button element, but not on a React button element.

    0 讨论(0)
  • 2021-02-09 06:10

    Refs are an escape hatch which allows you to get direct access to a DOM element or an instance of a component. In order to use them, you add a ref attribute to your component whose value is a callback function which will receive the underlying DOM element or the mounted instance of the component as its first argument.

    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>
        )
      }
    }
    

    refs can also be used with functional components by leveraging closures in JavaScript.

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

    ("Closures" just being a fancy way of saying referencing a variable that's declared outside the function - in this case, inputElement - within your function, in this case ref={(input) => inputElement = input}.)

    0 讨论(0)
  • 2021-02-09 06:18

    Refs are a way for you to get a handle back to the component you've created.

    ie.

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

    Then later in your code, you can access your text by doing:

    this.textComponent
    

    This will enable you to then invoke functions on the component in a object-oriented manner.

    I just want to point out that React/React-Native uses the declarative programming paradigm where data and "control" are managed through top-down passage of properties. Whereas in an imperative style you deal with objects and pointer and pass them around in order to invoke functions on them. Refs, in this case, is an escape hatch which allows you to get a declared component so that you can invoke functions on them in an imperative style.

    See the official React documentation for refs: https://reactjs.org/docs/refs-and-the-dom.html

    0 讨论(0)
提交回复
热议问题