This React warning occurs when a forwardRef render function is defined with an incorrect number of parameters. React expects forwardRef components to accept exactly two parameters: props and ref, but the function signature does not match this requirement.
This warning is displayed by React when you use React.forwardRef() but the render function you pass to it doesn't accept exactly two parameters. React's forwardRef API is designed to forward refs to child components, and it always calls your render function with two arguments: the props object and the ref object. The warning typically appears when you define a forwardRef component with only one parameter (just props) or with more than two parameters. This is problematic because React will still pass both arguments to your function, but if you only destructure props or define additional parameters, the ref won't be properly received or forwarded. Even if you don't intend to use the ref parameter, React requires you to include it in the function signature to maintain consistency and avoid potential issues. The ref parameter may be null if no ref was passed from the parent component, but it must still be present in the function signature.
Check your console warning to identify which component is triggering the error. The warning will typically indicate the component name or location in your code.
Look for code patterns like this:
// ❌ Incorrect - only one parameter
const MyInput = forwardRef((props) => {
return <input {...props} />;
});
// ❌ Incorrect - more than two parameters
const MyButton = forwardRef((props, ref, extra) => {
return <button ref={ref} {...props} />;
});Modify your forwardRef render function to accept exactly two parameters. The first parameter should be props, and the second should be ref:
// ✅ Correct - two parameters
const MyInput = forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});If using a named function:
// ✅ Correct - named function with two parameters
const MyInput = forwardRef(function MyInput(props, ref) {
return <input ref={ref} {...props} />;
});With TypeScript:
// ✅ Correct - TypeScript with proper typing
const MyInput = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
return <input ref={ref} {...props} />;
});Once you've added the ref parameter, make sure to actually use it by passing it to the element or component that should receive the ref:
// ✅ Forward ref to native element
const FancyButton = forwardRef((props, ref) => {
return (
<button ref={ref} className="fancy-button">
{props.children}
</button>
);
});
// ✅ Forward ref to another component
const FormInput = forwardRef((props, ref) => {
return (
<div className="form-group">
<input ref={ref} type="text" {...props} />
</div>
);
});If you need to use the ref internally and expose custom methods, use useImperativeHandle:
const CustomInput = forwardRef((props, ref) => {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current?.focus();
},
clear: () => {
if (inputRef.current) inputRef.current.value = '';
}
}));
return <input ref={inputRef} {...props} />;
});Verify that your forwardRef component properly forwards the ref by testing it in a parent component:
function ParentComponent() {
const inputRef = useRef(null);
const handleFocus = () => {
// This should work if ref is properly forwarded
inputRef.current?.focus();
};
return (
<div>
<MyInput ref={inputRef} placeholder="Enter text" />
<button onClick={handleFocus}>Focus Input</button>
</div>
);
}Check that:
- No warnings appear in the console
- The ref correctly points to the expected element
- Methods like focus(), scrollIntoView(), etc. work as expected
React 19 Changes: In React 19 and later, forwardRef is no longer necessary. You can pass ref as a regular prop instead. The forwardRef API will be deprecated in a future release. For React 19+, you can simply write:
// React 19+ - no forwardRef needed
function MyInput(props) {
return <input ref={props.ref} {...props} />;
}Common Patterns: When working with forwardRef, you may need to handle both internal refs and forwarded refs. This can be accomplished using callback refs or by combining refs:
const MyComponent = forwardRef((props, forwardedRef) => {
const internalRef = useRef(null);
// Combine both refs
const setRefs = useCallback((element) => {
internalRef.current = element;
if (typeof forwardedRef === 'function') {
forwardedRef(element);
} else if (forwardedRef) {
forwardedRef.current = element;
}
}, [forwardedRef]);
return <input ref={setRefs} {...props} />;
});TypeScript Best Practices: When using forwardRef with TypeScript, provide explicit type parameters for better type safety:
interface MyInputProps {
placeholder?: string;
value?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
}
const MyInput = forwardRef<HTMLInputElement, MyInputProps>(
(props, ref) => {
return <input ref={ref} {...props} />;
}
);
// Add display name for better debugging
MyInput.displayName = 'MyInput';Performance Considerations: forwardRef does not add significant performance overhead, but if you're creating many forwardRef components, ensure you're not recreating them unnecessarily. Define them outside render functions or memoize them appropriately.
React.FC expects children prop to be defined
React.FC no longer includes implicit children prop
Warning: You provided a `selected` prop to a form field without an `onChange` handler
You provided a 'selected' prop without an onChange handler
Failed to load source map from suspense chunk
How to fix "Failed to load source map from suspense chunk" in React
Prop spreading could cause security issues
Prop spreading could cause security issues
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency