How to fix Cannot read property "current" of null in React
This error occurs when accessing ref.current before the ref is initialized or when a forwarded ref is not properly set up. The ref object exists but its current property is null because the component hasn't mounted yet or the ref wasn't passed correctly through forwardRef.
Quick fix
Fixes TypeError
function ParentComponent() {
const childRef = useRef(null);
// ❌ Wrong: Accessing during render
// console.log(childRef.current); // null!
// ✅ Correct: Access in useEffect
useEffect(() => {
if (childRef.current) {
console.log(childRef.current); // Now available
childRef.current.focus();
}
}, []);
// ✅ Correct: Access in event handler
const handleClick = () => {
if (childRef.current) {
childRef.current.scrollIntoView();
}
};
return (
<>
<ChildComponent ref={childRef} />
<button onClick={handleClick}>Scroll to child</button>
</>
);
}- Access refs only after mounting
- Implement forwardRef correctly
- Use useImperativeHandle for custom ref values
- Handle conditional rendering properly
function ParentComponent() {const childRef = useRef(null);// ❌ Wrong: Accessing during render// console.log(childRef.current); // null!// ✅ Correct: Access in useEffectuseEffect(() => {if (childRef.current) {console.log(childRef.current); // Now availablechildRef.current.focus();}}, []);// ✅ Correct: Access in event handlerconst handleClick = () => {if (childRef.current) {childRef.current.scrollIntoView();}};return (<><ChildComponent ref={childRef} /><button onClick={handleClick}>Scroll to child</button></>);}Cannot read property "current" of null
What this error means
This TypeError happens when you try to access the `current` property of a ref that is `null` rather than a valid ref object. This is particularly common when using React's `forwardRef` API, which allows parent components to access a child component's DOM node or instance. The error typically occurs in one of three scenarios: accessing the ref too early in the component lifecycle (before the component has mounted), forgetting to pass the ref prop down to a DOM element or component, or incorrectly implementing the forwardRef wrapper. When a ref is forwarded but not attached to anything, React initializes it as `null` rather than `undefined`, leading to this specific error message. Understanding the timing of ref initialization is crucial. Refs are only populated after the component mounts and the underlying DOM node is created. Attempting to access `ref.current` during render or in synchronous code outside of effects or event handlers will often result in this error.
Typical symptoms
- TypeError: Cannot read property "current" of null appears in console
- Accessing ref.current in render or constructor throws error
- Parent component cannot interact with child component methods
- useImperativeHandle methods are undefined or inaccessible
- Ref works in some renders but is null in others
- Fast refresh in development causes ref to become empty object
Common causes
- Accessing ref.current before component has mounted
- forwardRef component not passing ref to underlying DOM element
- Missing ref prop when using forwardRef wrapper
- Attempting to access ref during render instead of in useEffect or event handler
- Conditional rendering causes component to unmount before ref is accessed
- Parent component tries to use ref immediately after render without waiting
- useImperativeHandle dependencies cause ref to reinitialize
- Fast refresh in Next.js creates empty ref object instead of proper ref
How to fix "Cannot read property "current" of null"
Ensure you access ref.current only after the component has mounted, typically in a useEffect hook or event handler:
function ParentComponent() {
const childRef = useRef(null);
// ❌ Wrong: Accessing during render
// console.log(childRef.current); // null!
// ✅ Correct: Access in useEffect
useEffect(() => {
if (childRef.current) {
console.log(childRef.current); // Now available
childRef.current.focus();
}
}, []);
// ✅ Correct: Access in event handler
const handleClick = () => {
if (childRef.current) {
childRef.current.scrollIntoView();
}
};
return (
<>
<ChildComponent ref={childRef} />
<button onClick={handleClick}>Scroll to child</button>
</>
);
}Always use null checks (if (ref.current)) before accessing ref properties.
When creating a component that needs to expose a ref, wrap it with forwardRef and attach the ref to a DOM element:
import { forwardRef } from 'react';
// ❌ Wrong: Not forwarding ref
function MyInput(props) {
return <input {...props} />;
}
// ✅ Correct: Forwarding ref to DOM element
const MyInput = forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
// Usage
function Parent() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current?.focus(); // Safe access with optional chaining
}, []);
return <MyInput ref={inputRef} />;
}The second parameter of the forwardRef callback is the ref passed from the parent. You must attach it to a DOM element or pass it to another forwardRef component.
When you want to expose specific methods rather than the DOM element itself, use useImperativeHandle:
import { forwardRef, useRef, useImperativeHandle } from 'react';
const CustomInput = forwardRef((props, ref) => {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current?.focus();
},
scrollIntoView: () => {
inputRef.current?.scrollIntoView({ behavior: 'smooth' });
},
getValue: () => {
return inputRef.current?.value || '';
}
}), []); // Empty dependency array
return <input ref={inputRef} {...props} />;
});
// Usage
function Parent() {
const customRef = useRef(null);
const handleAction = () => {
customRef.current?.focus(); // Call exposed method
console.log(customRef.current?.getValue());
};
return (
<>
<CustomInput ref={customRef} />
<button onClick={handleAction}>Focus Input</button>
</>
);
}Always include null checks when calling imperative handle methods.
If your component may be conditionally rendered or unmounted, always check if the ref is still valid:
function Parent() {
const [show, setShow] = useState(true);
const childRef = useRef(null);
const handleInteraction = () => {
// ❌ Wrong: Ref might be null if component unmounted
// childRef.current.doSomething();
// ✅ Correct: Check before using
if (childRef.current) {
childRef.current.doSomething();
}
};
useEffect(() => {
// Only run effect if component is mounted
if (show && childRef.current) {
childRef.current.initialize();
}
// Cleanup when unmounting
return () => {
if (childRef.current) {
childRef.current.cleanup?.();
}
};
}, [show]);
return (
<>
{show && <Child ref={childRef} />}
<button onClick={() => setShow(!show)}>Toggle</button>
<button onClick={handleInteraction}>Interact</button>
</>
);
}Consider using optional chaining (ref.current?.method()) for cleaner null-safe access.
When working with third-party libraries that may not handle forwarded refs properly, create a fallback:
import { useState, useRef, forwardRef } from 'react';
const ComponentWithFallback = forwardRef((props, forwardedRef) => {
// Create fallback ref using lazy initialization
const [fallbackRef] = useState(() =>
forwardedRef || useRef(null)
);
const ref = forwardedRef || fallbackRef;
// Use ref normally
useEffect(() => {
if (ref.current) {
ref.current.focus();
}
}, [ref]);
return <input ref={ref} {...props} />;
});
// Alternative: Check ref type
const SafeComponent = forwardRef((props, forwardedRef) => {
const localRef = useRef(null);
// Use forwarded ref if valid, otherwise use local
const activeRef =
forwardedRef && typeof forwardedRef === 'object' && 'current' in forwardedRef
? forwardedRef
: localRef;
return <input ref={activeRef} {...props} />;
});This pattern prevents errors when refs are passed incorrectly or not at all.
Advanced notes
React 19 Changes: Starting with React 19, ref is available as a regular prop, making forwardRef less necessary. The forwardRef API will be deprecated in future versions, so consider updating components to use ref as a prop when targeting React 19+.
TypeScript Considerations: When using TypeScript with refs, you may encounter "Object is possibly null" errors. Use type guards (if (ref.current)) or the non-null assertion operator (ref.current!) carefully. For better type safety, define the ref type explicitly: const ref = useRef<HTMLInputElement>(null).
Fast Refresh Issues: In Next.js and some development environments, fast refresh can occasionally cause refs to become empty objects instead of proper ref objects, leading to "can't define property 'current'" errors. This is typically resolved by doing a full page refresh rather than a fast refresh.
Ref Callback Pattern: For more control over ref timing, use the callback ref pattern: <div ref={(node) => { if (node) { /* safe to use */ } }} />. This callback is invoked immediately when the element is mounted and with null when unmounted.
Multiple Refs: When you need both a local ref and a forwarded ref, merge them using a callback: const setRefs = useCallback((node) => { localRef.current = node; if (forwardedRef) forwardedRef.current = node; }, [forwardedRef]), then use <div ref={setRefs} />.
Performance: Accessing ref.current repeatedly in render can cause issues. Cache the value in a variable within effects or handlers: const element = ref.current; if (element) { /* use element */ }.
Frequently asked questions
- What does "TypeError" mean?
- This TypeError happens when you try to access the current property of a ref that is null rather than a valid ref object. This is particularly common when using React's forwardRef API, which allows parent components to access a child component's DOM node or instance. The error typically occurs in one of three scenarios: accessing the ref too early in the component lifecycle (before the component has mounted), forgetting to pass the ref prop down to a DOM element or component, or incorrectly implementing the forwardRef wrapper.
- How do I fix "TypeError"?
- This error occurs when accessing ref.current before the ref is initialized or when a forwarded ref is not properly set up. The ref object exists but its current property is null because the component hasn't mounted yet or the ref wasn't passed correctly through forwardRef.
- What causes "TypeError"?
- Accessing ref.current before component has mounted forwardRef component not passing ref to underlying DOM element Missing ref prop when using forwardRef wrapper
- Is the "TypeError" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.