How to fix Cannot access ref.current in forwardRef before component renders in React
This error occurs when you try to access ref.current during the render phase of a component using forwardRef, before React has attached the ref to a DOM node. Refs are only populated after the component mounts and the DOM element is created.
Quick fix
Fixes Cannot access ref.current in forwardRef before component renders
import React, { forwardRef, useEffect } from 'react';
const MyInput = forwardRef<HTMLInputElement>((props, ref) => {
// ❌ WRONG: Accessing ref.current during render
// console.log(ref.current); // Error!
useEffect(() => {
// ✅ CORRECT: Access ref.current after render
if (ref && typeof ref !== 'function' && ref.current) {
console.log('Input element:', ref.current);
ref.current.focus(); // Safe to call DOM methods
}
}, [ref]);
return <input ref={ref} {...props} />;
});- Move ref.current access to useEffect
- Add null checks before accessing ref.current
- Use useLayoutEffect for synchronous DOM reads
- Handle conditional rendering carefully
import React, { forwardRef, useEffect } from 'react';const MyInput = forwardRef<HTMLInputElement>((props, ref) => {// ❌ WRONG: Accessing ref.current during render// console.log(ref.current); // Error!useEffect(() => {// ✅ CORRECT: Access ref.current after renderif (ref && typeof ref !== 'function' && ref.current) {console.log('Input element:', ref.current);ref.current.focus(); // Safe to call DOM methods}}, [ref]);return <input ref={ref} {...props} />;});Cannot access ref.current in forwardRef before component renders
What this error means
This error happens when you attempt to read or write `ref.current` during the render phase of a React component that uses `forwardRef`. React refs follow a specific lifecycle: they are `null` or `undefined` until after the component has rendered and React has attached the ref to the actual DOM node. When using `forwardRef`, the ref parameter is passed to your component, but it won't have a `.current` value until React completes the render and commit phases. Accessing `ref.current` during rendering breaks React's expectation that components behave like pure functions, making the component's output unpredictable. React cannot track changes to `ref.current` during rendering, which means it won't know when to re-render your component. This is by design - refs are meant for accessing imperative DOM APIs or storing mutable values that don't affect rendering.
Typical symptoms
- Error thrown when accessing ref.current during component render
- ref.current is null or undefined even though a ref was passed
- Component crashes before mounting completes
- Unexpected behavior when trying to use ref.current in JSX
- TypeScript errors about ref.current being possibly null
Common causes
- Accessing ref.current directly in the component body during render
- Reading ref.current in conditional rendering logic
- Using ref.current to compute derived state or props during render
- Calling methods on ref.current before useEffect or useLayoutEffect runs
- Attempting to access ref.current when the element is conditionally rendered and not yet mounted
- Not checking if ref.current exists before accessing it
How to fix "Cannot access ref.current in forwardRef before component renders"
The most common fix is to move any ref.current access into a useEffect hook, which runs after the component renders and the ref is attached:
import React, { forwardRef, useEffect } from 'react';
const MyInput = forwardRef<HTMLInputElement>((props, ref) => {
// ❌ WRONG: Accessing ref.current during render
// console.log(ref.current); // Error!
useEffect(() => {
// ✅ CORRECT: Access ref.current after render
if (ref && typeof ref !== 'function' && ref.current) {
console.log('Input element:', ref.current);
ref.current.focus(); // Safe to call DOM methods
}
}, [ref]);
return <input ref={ref} {...props} />;
});For immediate DOM manipulation before paint, use useLayoutEffect instead of useEffect.
Always check that the ref exists and has a .current property before accessing it:
import React, { forwardRef, useEffect } from 'react';
const CustomComponent = forwardRef<HTMLDivElement>((props, ref) => {
useEffect(() => {
// Check if ref is an object with current property
if (ref && typeof ref !== 'function' && ref.current) {
// Safe to access ref.current here
const element = ref.current;
element.style.backgroundColor = 'lightblue';
}
}, [ref]);
return <div ref={ref}>Content</div>;
});TypeScript users can use optional chaining for cleaner code: ref?.current.
If you need to read DOM properties (like dimensions) before the browser paints, use useLayoutEffect:
import React, { forwardRef, useLayoutEffect, useState } from 'react';
const MeasuredComponent = forwardRef<HTMLDivElement>((props, ref) => {
const [height, setHeight] = useState(0);
useLayoutEffect(() => {
if (ref && typeof ref !== 'function' && ref.current) {
// Measure DOM before browser paints
const rect = ref.current.getBoundingClientRect();
setHeight(rect.height);
}
}, [ref]);
return (
<div ref={ref}>
Height: {height}px
{props.children}
</div>
);
});Note: useLayoutEffect blocks browser painting, so use it only when necessary.
When the element attached to the ref is conditionally rendered, the ref may remain null even inside effects:
import React, { forwardRef, useEffect } from 'react';
interface Props {
show: boolean;
}
const ConditionalInput = forwardRef<HTMLInputElement, Props>(
({ show }, ref) => {
useEffect(() => {
if (ref && typeof ref !== 'function' && ref.current) {
ref.current.focus();
}
// ref.current will be null if show is false
}, [ref, show]); // Include show in dependencies
// Only render input when show is true
if (!show) return null;
return <input ref={ref} placeholder="Type here..." />;
}
);The ref will only have a .current value when the element is actually rendered.
Callback refs give you more control over when and how refs are set:
import React, { forwardRef, useCallback } from 'react';
const SmartInput = forwardRef<HTMLInputElement>((props, forwardedRef) => {
const handleRef = useCallback(
(node: HTMLInputElement | null) => {
// Called when element mounts
if (node) {
console.log('Element mounted:', node);
node.focus();
}
// Forward the ref to parent
if (typeof forwardedRef === 'function') {
forwardedRef(node);
} else if (forwardedRef) {
forwardedRef.current = node;
}
},
[forwardedRef]
);
return <input ref={handleRef} {...props} />;
});Callback refs are called immediately when the element is attached or detached.
Advanced notes
React 19 Update: In React 19, forwardRef is no longer necessary. You can pass ref as a regular prop:
// React 19
function MyInput({ ref }) {
return <input ref={ref} />;
}Fallback Ref Pattern: If you want a component to have its own internal ref even when no ref is forwarded, use a fallback pattern:
import React, { forwardRef, useRef } from 'react';
const ComponentWithFallback = forwardRef<HTMLDivElement>((props, forwardedRef) => {
const fallbackRef = useRef<HTMLDivElement>(null);
const ref = forwardedRef || fallbackRef;
// Now ref will always have a value, even if parent doesn't pass one
return <div ref={ref as React.RefObject<HTMLDivElement>}>Content</div>;
});useImperativeHandle: When using forwardRef with useImperativeHandle, remember that the imperative methods won't be available until after the component mounts:
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
interface CustomHandle {
focus: () => void;
}
const CustomInput = forwardRef<CustomHandle>((props, ref) => {
const inputRef = useRef<HTMLInputElement>(null);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current?.focus();
},
}));
return <input ref={inputRef} />;
});
// Parent usage
function Parent() {
const ref = useRef<CustomHandle>(null);
useEffect(() => {
// Safe to call after mount
ref.current?.focus();
}, []);
return <CustomInput ref={ref} />;
}Performance Consideration: Accessing refs doesn't trigger re-renders, which is why you can't use ref.current as a dependency in rendering logic. If you need a value that affects rendering, use useState instead.
Frequently asked questions
- What does "Cannot access ref.current in forwardRef before component renders" mean?
- current during the render phase of a React component that uses forwardRef. React refs follow a specific lifecycle: they are null or undefined until after the component has rendered and React has attached the ref to the actual DOM node. current value until React completes the render and commit phases.
- How do I fix "Cannot access ref.current in forwardRef before component renders"?
- This error occurs when you try to access ref.current during the render phase of a component using forwardRef, before React has attached the ref to a DOM node. Refs are only populated after the component mounts and the DOM element is created.
- What causes "Cannot access ref.current in forwardRef before component renders"?
- Accessing ref.current directly in the component body during render Reading ref.current in conditional rendering logic Using ref.current to compute derived state or props during render
- Is the "Cannot access ref.current in forwardRef before component renders" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.