Inline ref functions in React

Inline ref functions in React

Introduction

In React, you can use inline functions to get element references (refs), but this approach has some nuances and is generally not recommended due to performance issues.

I tried it in one of my projects and realized that the function kept running on every render. Which led to this blog post haha.

How inline ref functions work

Inline ref functions are defined directly within the JSX of a component. When you use an inline function for a ref, React calls this function twice during renders: first with null to clear the previous ref, and then with the new DOM element. This happens because a new instance of the function is created with each render, so React needs to clear the old ref and set up the new one.

Example of inline ref function

function MyComponent() {
  let inputRef;

  return (
    <div>
      <input
        ref={(el) => {
          inputRef = el;
        }}
      />
      <button onClick={() => console.log(inputRef)}>Log Input Ref</button>
    </div>
  );
}

In this example, the inline function (el) => { inputRef = el; } is called twice on each render: once with null and once with the actual DOM element.

How is useRef different?

  • useRefs aren't called twice on each render. They only set the ref once, even if re-renders happen, they're stable.

  • useRefs are more performant.

When to use inline ref functions

As mentioned, they should be used sparingly, but can be useful when you need:

  • Dynamic refs.

  • Conditional refs.

Example of a dynamic ref

function DynamicRefsComponent({ items }) {
  const refs = {};

  return (
    <div>
      {items.map((item, index) => (
        <div
          key={index}
          ref={(el) => { refs[item.id] = el; }}
        >
          {item.content}
        </div>
      ))}
      <button onClick={() => console.log(refs)}>Log All Refs</button>
    </div>
  );
}

Here we store the refs in a refs object. This is dynamically created by the ref prop. We associate each ref with the id of the item.

Mind you, you're rarely gonna do this when working with React. I've never needed to do this. I literally had to look up when inline ref functions are useful because I couldn't think of a situation myself.

Conclusion

Inline ref functions should be used sparingly.