no-forward-ref
Replaces usage of 'forwardRef' with passing 'ref' as a prop.
Full Name in eslint-plugin-react-x
react-x/no-forward-refFull Name in @eslint-react/eslint-plugin
@eslint-react/no-forward-refFeatures
🔄
Presets
x
recommended
recommended-typescript
recommended-type-checked
strict
strict-typescript
strict-type-checked
Rule Details
In React 19, forwardRef is no longer necessary. Pass ref as a prop instead.
forwardRef will be deprecated in a future release. Learn more here.
Examples
Wrapping function components with forwardRef
Starting from React 19, you can pass ref as a regular prop directly, without using forwardRef.
import React, { forwardRef } from "react";
// Problem: Using forwardRef to pass ref
const MyInput = forwardRef(function MyInput(props, ref) {
return <input ref={ref} {...props} />;
});// Recommended: Receive ref as a regular prop
function MyInput({ ref, ...props }) {
return <input ref={ref} {...props} />;
}Using typed React.forwardRef
Even with TypeScript generics, forwardRef can be replaced with a simpler props-based approach.
import React from "react";
interface MyInputProps {
value: string;
onChange: (value: string) => void;
}
// Problem: Using React.forwardRef with generic parameters
const MyInput = React.forwardRef<MyInputProps, HTMLInputElement>(
function MyInput({ value, onChange }, ref) {
return (
<input
ref={ref}
value={value}
onChange={(e) => onChange(e.target.value)}
/>
);
},
);import React from "react";
interface MyInputProps {
value: string;
onChange: (value: string) => void;
}
// Recommended: Declare ref directly in the props type
function MyInput({
ref,
value,
onChange,
}: MyInputProps & { ref?: React.RefObject<HTMLInputElement> | null }) {
return <input ref={ref} value={value} onChange={(e) => onChange(e.target.value)} />;
}Passing ref through a component tree in React 19
In React 19, ref can be passed like any other prop, making it easy to forward refs through intermediate components without forwardRef.
// Recommended: Pass ref as a regular prop through multiple layers
import { useRef } from "react";
function MyInput({ ref, ...props }: React.InputHTMLAttributes<HTMLInputElement> & { ref?: React.Ref<HTMLInputElement> }) {
return <input ref={ref} {...props} />;
}
function FormField({ ref, label, ...props }: React.InputHTMLAttributes<HTMLInputElement> & { ref?: React.Ref<HTMLInputElement>; label: string }) {
return (
<label>
{label}
<MyInput ref={ref} {...props} />
</label>
);
}
export default function Form() {
const ref = useRef<HTMLInputElement>(null);
function handleClick() {
ref.current?.focus();
}
return (
<form>
<FormField label="Enter your name:" ref={ref} placeholder="Name" />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}