In Frontend (React, Javascript) By Leigh Halliday February 25, 2018 Leigh Halliday

Using Refs in React

As of React 16.3 there will be a new way to create "refs" (references to the actual underlying DOM element). Below we'll go over each one and talk about its pros and cons.

To learn all about Refs from the React documentation, it's available here.

String Refs (deprecated)

This is an "older" way of creating refs and shouldn't be used, but we'll include it here for reference... no pun intended :) It is discouraged because it apparently makes it hard for the React team to optimize the underlying code.

// in render function:
<input type="text" defaultValue="First" ref="first" />;

// accessed with:
this.refs.first;

Callback Refs

These refs are when you pass a callback function to the ref prop, which will receive the element of the item you are creating a ref to. You can then assign it to a variable or use it how you wish.

// in render function:
<input
  type="text"
  defaultValue="Second"
  ref={input => (this.second = input)}
/>;

// accessed with:
this.second;

The New React.createRef()

In React 16.3 you'll be able to use the new React.createRef() function to make ref creation easier. If you're interested, here is the actual PR where the new functionality is introduced.

// declared in class
third = React.createRef();
// or in constructor
this.third = React.createRef();

// in render function:
<input type="text" defaultValue="Third" ref={this.third} />;

// to access this input:
this.third.value;

// to access input's value:
this.third.value.value;

Parent Access to Child Ref

You can simply pass one of the new React.createRef() values down to a child and it can assign that instead, giving its parent access to a specific element.

class Child extends Component {
  static propTypes = {
    fourth: PropTypes.shape({ value: PropTypes.instanceOf(HTMLInputElement) })
  };

  render() {
    return <input type="text" defaultValue="Fourth" ref={this.props.fourth} />;
  }
}

class Parent extends Component {
  fourth = React.createRef();

  render() {
    <Child fourth={this.fourth} />;
  }
}

// accessed with (in parent):
this.fourth.value;

Video Demo

Here is a video demo of the code we covered above and will take a look at below:

Full Code Example

Here is the full component(s) used when discussing refs in this article.

import React, { Component } from "react";
import PropTypes from "prop-types";

// To be used within the App component
class FormSection extends Component {
  static propTypes = {
    fourth: PropTypes.shape({ value: PropTypes.instanceOf(HTMLInputElement) })
  };

  render() {
    return <input type="text" defaultValue="Fourth" ref={this.props.fourth} />;
  }
}

export default class App extends Component {
  third = React.createRef();
  fourth = React.createRef();

  handleSubmit = e => {
    e.preventDefault();

    console.log(
      this.refs.first,
      this.second,
      this.third.value,
      this.fourth.value
    );

    // it's sort of weird to access the actual input value
    console.log(this.third.value.value);
  };

  render() {
    return (
      <form onSubmit={e => this.handleSubmit(e)}>
        <input type="text" defaultValue="First" ref="first" />

        <input
          type="text"
          defaultValue="Second"
          ref={input => (this.second = input)}
        />

        <input type="text" defaultValue="Third" ref={this.third} />

        <FormSection fourth={this.fourth} />

        <button>Submit</button>
      </form>
    );
  }
}