Senger CodeLab 🚀

How do I avoid Function components cannot be given refs when using react-router-dom

September 29, 2026

How do I avoid Function components cannot be given refs when using react-router-dom

Encountering the “Function components cannot be given refs” error in React while using react-router-dom can be a frustrating experience. This error typically arises when you attempt to directly attach a ref to a functional component. Unlike class components, functional components, by default, do not have instances, and therefore, cannot directly accept refs. This article addresses exactly how do I avoid ‘Function components cannot be given refs’ when using react-router-dom? We’ll explore various techniques, including using forwardRef, higher-order components, and understanding the underlying reasons behind this React behavior. This guide will provide practical solutions and clear examples to help you effectively manage refs within your React Router-powered applications, ensuring smooth navigation and component interactions. Let’s dive in and resolve this common React pitfall!

Understanding the Issue: Functional Components and Refs

At its core, the problem stems from the nature of functional components in React. Before the introduction of Hooks, functional components were primarily intended for presentational purposes – simply rendering UI based on props. They lacked internal state and lifecycle methods, which are characteristics of class components. Consequently, they also lacked component instances, which are necessary for attaching refs. A ref in React provides a way to access a DOM node or React element created in the render method. Since functional components didn’t have instances, React couldn’t directly associate a ref with them, resulting in the dreaded “Function components cannot be given refs” error. React’s official documentation explains this limitation in detail.

However, with the advent of Hooks, functional components gained the ability to manage state and perform side effects, blurring the lines between functional and class components. Despite these advancements, the fundamental issue regarding refs remained. React provides forwardRef to bridge this gap, allowing functional components to receive and pass refs down to their child components. This mechanism enables you to access underlying DOM elements within functional components, effectively solving the “Function components cannot be given refs” error. Understanding this historical context and the role of forwardRef is crucial for effectively managing refs in modern React applications.

Consider a scenario where you want to focus an input field within a custom functional component after the component mounts. Directly attaching a ref to the functional component won’t work. Instead, you need to use forwardRef to pass the ref to the input field inside the component. This allows you to programmatically focus the input field when the component is rendered, enhancing the user experience.

The Solution: forwardRef to the Rescue

The primary solution to the “Function components cannot be given refs” error is to use React.forwardRef. This higher-order component allows you to take a component that receives props and ref as arguments and return a React node. The ref is then passed down to a DOM element or another component that can accept refs. This enables you to access the underlying DOM element or component instance within your functional component. This is important because it allows you to interact directly with the DOM when necessary, bypassing the typical React data flow. This is especially useful when integrating with third-party libraries that manipulate the DOM directly.

Here’s how you can implement forwardRef: First, wrap your functional component with React.forwardRef. The forwardRef function takes a render function as its argument. This render function receives props and ref as parameters. Inside the render function, you can pass the ref down to the DOM element or component you want to access. This establishes a connection between the ref passed to the parent component and the underlying element in the child component. For example, if you have a custom input component, you can forward the ref to the actual input element within that component.

Featured Snippet: To avoid the “Function components cannot be given refs” error in React Router applications, use React.forwardRef. Wrap your functional component with React.forwardRef, which accepts a render function with props and ref as arguments. Pass the ref down to the DOM element you want to access within the component. This allows you to interact with the underlying DOM element, such as focusing an input field, while using functional components. This approach maintains the benefits of functional components (simplicity, testability) while providing the necessary ref capabilities.

Real-World Implementation with React Router

Integrating forwardRef with react-router-dom often involves managing focus or scroll positions after navigation. Imagine a scenario where you want to focus the first input field on a new page after a user navigates to it using a Link component. You can achieve this by creating a custom component that wraps the input field and uses forwardRef to expose the input’s DOM node. Then, when the route changes, you can use a useEffect hook in the parent component to access the input field via the ref and call the focus() method. This is a common pattern for improving the accessibility and usability of your application.

Consider this example: You have a SearchForm component that contains an input field. You want to automatically focus this input field when the user navigates to the search route. You can wrap the SearchForm component with forwardRef and pass the ref to the input field. In the parent component, which renders the SearchForm, you can use a useEffect hook to access the input field via the ref and call focus() after the component mounts. This ensures that the input field is focused whenever the user navigates to the search route. This approach requires careful handling of the ref to ensure it is correctly attached and accessible.

Here’s a practical list of steps for implementing this:

  1. Wrap your functional component with React.forwardRef.
  2. Accept props and ref as arguments in the render function.
  3. Pass the ref down to the DOM element or component you want to access.
  4. In the parent component, create a useRef hook to hold the ref.
  5. Pass the ref to your forwarded component.
  6. Use a useEffect hook to access the DOM element and manipulate it (e.g., focus it).

Alternative Approaches and Considerations

While forwardRef is the most common and recommended solution, there are alternative approaches, although they might not be as elegant or efficient. One approach is to use a render prop component. A render prop component accepts a function as a prop, and that function returns a React element. You can pass a ref to the render prop function and then use that ref to access the underlying DOM element. However, this approach can lead to more verbose code and might not be as readable as using forwardRef. Another alternative is to use a class component instead of a functional component. Class components can directly accept refs, but this approach sacrifices the benefits of using functional components, such as simplicity and testability. The React documentation provides further details on refs and the DOM.

Another consideration is the performance implications of using refs. While refs provide a way to directly interact with the DOM, they can also bypass React’s virtual DOM and lead to performance issues if not used carefully. It’s important to use refs sparingly and only when necessary. In most cases, you should prefer to use React’s state management and props to update the UI. However, there are certain scenarios where refs are essential, such as managing focus, animations, or integrating with third-party libraries. Using refs judiciously can help you maintain the performance and maintainability of your application. Consider using tools like the React Profiler to identify potential performance bottlenecks related to ref usage.

Here are some key points to remember:

  • forwardRef is the preferred solution for passing refs to functional components.
  • Avoid using refs unnecessarily, as they can bypass React’s virtual DOM.
  • Consider the performance implications of using refs in your application.
Infographic here showing a visual comparison of different ref strategies.
FAQ: Addressing Common Questions --------------------------------
Why can't I directly attach a ref to a functional component?
Functional components, by default, do not have instances, which are required for refs to be attached. forwardRef bridges this gap by allowing you to pass the ref down to a DOM element within the component.
When should I use forwardRef with react-router-dom?
Use forwardRef when you need to access or manipulate a DOM element within a functional component after a route change, such as focusing an input field or scrolling to a specific element.
Are there any performance considerations when using forwardRef?
While forwardRef is generally efficient, excessive use of refs can bypass React's virtual DOM and potentially lead to performance issues. Use them judiciously and consider alternative approaches when possible. [Kent C. Dodds' blog](https://kentcdodds.com/blog/use-cases-for-react-refs) has great tips on ref use cases.
What are the alternatives to forwardRef?
Alternatives include render props or using class components, but forwardRef is generally the most elegant and recommended solution for functional components.
By understanding the problem and implementing the correct solutions, you can easily overcome the "Function components cannot be given refs" error. Remember to use forwardRef when necessary, and always consider the performance implications of directly manipulating the DOM. With these techniques in mind, you'll be well-equipped to build robust and interactive React applications with react-router-dom. The key is to think about where the actual DOM element resides and ensure the ref is correctly forwarded to it.

As you continue building your React applications, consider exploring other advanced React Router concepts such as custom history management or dynamic route matching. Experiment with different approaches to handling refs and DOM manipulation to deepen your understanding and refine your skills. Take the time to analyze your application’s performance and identify areas where you can optimize your code. If you’re ready to take your React skills to the next level, explore our other articles on advanced React patterns and best practices, or perhaps explore our React development services.

  • Use React.forwardRef
  • Remember to pass the ref to the correct DOM element

Question & Answer :
I have the following (using Material UI)….

import React from "react"; import { NavLink } from "react-router-dom"; import Tabs from "@material-ui/core/Tabs"; import Tab from "@material-ui/core/Tab"; function LinkTab(link){ return <Tab component={NavLink} to={link.link} label={link.label} value={link.link} key={link.link} />; } 

In the new versions this causes the following warning…

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of ForwardRef. in NavLink (created by ForwardRef)

I tried changing to…

function LinkTab(link){ // See https://material-ui.com/guides/composition/#caveat-with-refs const MyLink = React.forwardRef((props, ref) => <NavLink {...props} ref={ref} />); return <Tab component={MyLink} to={link.link} label={link.label} value={link.link} key={link.link} />; } 

But I still get the warning. How do I resolve this issue?

Just give it as innerRef,

// Client.js <Input innerRef={inputRef} /> 

Use it as ref.

// Input.js const Input = ({ innerRef }) => { return ( <div> <input ref={innerRef} /> </div> ) }