Donate to the Palestine's children, safe the people of Gaza.  >>>Donate Link...... Your contribution will help to save the life of Gaza people, who trapped in war conflict & urgently needed food, water, health care and more.

Refs-and- key- in-React

First off, let me express that this is generally not the way to go about things in React land. Usually what you want to do is pass down functionality to children in props, and pass up notifications from children in events (or better yet: dispatch).

But if you must expose an imperative method on a child component, you can use refs. Remember this is an escape hatch and usually indicates a better design is available.

Using Hooks and Function Components

const { forwardRef, useRef, useImperativeHandle } = React

// We need to wrap component in `forwardRef` in order to gain
// access to the ref object that is assigned using the `ref` prop.
// This ref is passed as the second parameter to the function component.
const Child = forwardRef((props, ref) => {
  // The component instance will be extended
  // with whatever you return from the callback passed
  // as the second argument
  useImperativeHandle(ref, () => ({
    getAlert() {
      alert("getAlert from Child")
    },
  }))

  return <h1>Hi</h1>
})

// useImperativeHandle customizes the instance value that is exposed to parent components when using ref.

const Parent = () => {
  // In order to gain access to the child component instance,
  // you need to assign it to a `ref`, so we call `useRef()` to get one
  const childRef = useRef()

  return (
    <div>
      <Child ref={childRef} />
      <button onClick={() => childRef.current.getAlert()}>Click</button>
    </div>
  )
}

ReactDOM.render(<Parent />, document.getElementById("root"))

The significance of keys and refs. The names of these attributes speak for themselves: both keys and refs are used to identify particular elements in the DOM, however their purposes are different.

Official Doc – Refs and the DOM

Sometimes when using React.js you’ll need an escape hatch to write imperative-style code to interact directly with DOM elements. Using React’s createRef method allows you to do just that!

React provides a way to get references to DOM nodes by using React.createRef(). It’s really just an equivalent of this all-too-familiar snippet of JavaScript:

document.getElementById('foo-id');

This is exactly what React.createRef() does, although it requires a bit of a different setup.

refs are used to get reference to a DOM node or an instance of a component in a React Application i.e. refs would return the node we are referencing .

Similarly to keys refs are added to elements in the form of attributes. According to React.js documentation some of the best cases for using refs are: managing focus, text selection, or media playback, triggering animations, and integrating with third-party DOM libraries.

In the typical React dataflow, props are the only way that parent components interact with their children. To modify a child, you re-render it with new props. However, there are a few cases where you need to imperatively modify a child outside of the typical dataflow. In other words, in some cases you might need to modify a child without re-rendering it with new props. That’s exactly when refs attribute comes to use. The child to be modified could be an instance of a React component, or it could be a DOM element. For both of these cases, React provides an escape hatch.

https://alligator.io/react/createref/

class Foobar extends Component {
  constructor(props) {
    super(props);
    this.myInput = React.createRef();    // initialize "this.myInput"
  }

  render() {
    return (
      <input ref={this.myInput}/>        {/* pass "this.myInput" as prop */}
    );
  }
}

All standard HTML elements in React have a reserved prop called ref (much like style which is a reserved prop). Simply pass the ref you initialized in the constructor to the ref prop… and voila! You can start interacting with the DOM node by using this.myInput.current

this.myInput.current holds the reference to the DOM node

Example: Focusing an Taking that last code snippet, let’s make the most common use-case of createRef() to demonstrate how we could start interacting with the DOM node:

export default class App extends Component {
  constructor(props) {
    super(props)
    this.myInput = React.createRef()
  }
  render() {
    return (
      <div>
        <input ref={this.myInput} />

        <button
          onClick={() => {
            this.myInput.current.focus()
          }}
        >
          focus!
        </button>
      </div>
    )
  }
}

The API is very simple. You first define a ref, assign it to the element you want to manipulate and call focus on ref’s current property.

Calling the focus() method isn’t a React.js thing… it’s a normal JavaScript thing! 💃🏻💃🏻 For example, this is how it’s done with vanilla JavaScript:

document.getElementById('myInput').focus();

Now, this is how to achieve the same example above using callback refs:

class SimpleCallbackRef extends Component {
  onClick() {
    this.inputRef.focus()
  }

  render() {
    return (
      <div>
        <input
          ref={ref => {
            this.inputRef = ref
          }}
        />
        <button onClick={this.onClick.bind(this)}>Click to Focus</button>
      </div>
    )
  }
}

Notice that although you don’t need to manually create a ref anymore, the callback function ref => { this.inputRef = ref; } looks less natural.

Refs with React Hooks Using useRef

Refs in React Hooks aren’t much different than class components. It’s achieved using the useRef hook. Just remember to omit this and you are golden

function App() {

  const myInput = useRef(null);

  return (
    <div>
      <input ref={myInput}/>
      <button onClick={() => {
        myInput.current.focus();
      }}>
        focus!
      </button>
    </div>
  );
}

Multiple APIs

When refs were first born, the React team encouraged the use of string refs. This is no longer the case as this API will be deprecated. A powerful alternative was introduced: callback refs. But all this power came with a price – callback refs are more verbose and may behave oddly. In order to simplify things, the createRef API came into play. And finally, after Hooks were introduced, useRef emerged. But, because there are four ways of doing the same thing, people started losing faith in refs. Let’s fix this.

should we use callback refs or the createRef API?

The short answer is that most of the time you can safely use the createRef API. Although you can always achieve the same result using callback refs, recall that this new API was specially crafted in order to simplify your experience. You can look at its RFC in order to understand the React team’s motivations behind it. In short, the goal was to maintain the simplicity of the deprecated string refs and purposely keep a simple API, leaving callback refs for more complex use cases.

Note, You can’t use createRef for pure functional components since they lack many of the React-y features like state & lifecycle components

Finally, as a rule of thumb:

  • Don’t overuse refs
  • Abolish string refs
  • Use callback refs when you have to dynamically set them
  • When in a class component, use createRef in all other cases
  • When in a function component, use useRef in all other cases
  • Use forwardRef when you need access to a child ref
  • Use Hooks to empower your function component
  • If the child ref must not be a function component, then use a custom method to trigger focus programmatically from the parent (remember you will get a component instance, not a DOM element)

Keys

Keys React are utilised to identify specific Virtual DOM Elements that have changed. The classic example of usage of keys is a list. Let’s imagine we have an array of objects:

fruits = [{name: "Pineapple", id: 1}, {name: "Banana", id: 2}, {name: "Passion Fruit", id: 3}

If we were to pass this array as a prop to a FruitList component in order to render a list of fruits onto the page, we would iterate through our array of fruits, rendering each one as a list item:

const FruitList = (props) => {
    const fruits = props.fruits.map(fruit =>
    <li>{fruit.name}</li>
   )
   return (
       <ul>
        {fruits}
       </ul>
   )
}

This works and does indeed render the list of fruits. However at any moment we might want to add new fruits, as well as delete or modify the existing ones. How would React know to perform those changes efficiently? That’s where the key attribute comes in handy. There are usually several choices for creating element’s unique identity. One of them is using existing IDs of each object:

const FruitList = (props) => {
    const fruits = props.fruits.map(fruit =>
    <li key={fruit.id}>{fruit.name}</li>
   )
   return (
       <ul>
        {fruits}
       </ul>
   )
}

You might also find yourself in a situation when items in your array don’t really possess a unique ID. In case of no stable IDs for rendered items, index of iterator may be used as a key.

const FruitList = (props) => {
    const fruits = props.fruits.map((fruit, index) =>
    <li key={index.id}>{fruit.name}</li>
   )
   return (
       <ul>
        {fruits}
       </ul>
   )
}

An important note for key usage is that they only have to be unique among their siblings. Keys don’t have to be globally unique, meaning that the same keys can be used for two different arrays.

When you need refs instead of ID’s ?

As we all know , ID’s works on a single element in whole DOM tree thus lets say we want to change the background-color on focus . With ID’s this will happen but only the first input box will get the red color

As Bob comes before Tim and both have the same ID on which background manipulation code runs but only Bob gets angry on focus not Tim. If we use refs we can replace the IDs with the a particular ref name and we should be doing fine. But i would suggest using classes for use-case of this kind as its much better and also refs has its caveats which we would see soon.

Further Reading

https://moduscreate.com/blog/everything-you-need-to-know-about-refs-in-react/

All refs in one place



To Get Daily Health Newsletter

We don’t spam! Read our privacy policy for more info.

Download Mobile Apps
Follow us on Social Media
© 2012 - 2025; All rights reserved by authors. Powered by Mediarx International LTD, a subsidiary company of Rx Foundation.
RxHarun
Logo