Case I, I can accept those code as the picture shows, we define the ref in parent component and pass it to child component
App.js
import { useRef } from 'react';
import MyInput from './MyInput.js';
export default function Form() {
const ref = useRef(null);
function handleClick() {
ref.current.focus();
}
return (
<form>
<MyInput label="Enter your name:" ref={ref} />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}
MyInput.js
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
const { label, ...otherProps } = props;
return (
<label>
{label}
<input {...otherProps} ref={ref} />
</label>
);
});
export default MyInput;
Case II,the component Input was defined as following ,
import * as React from 'react'
import { cn } from '@/lib/utils'
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
)
}
)
Input.displayName = 'Input'
export { Input }
this was used in another file chat.js, the episoid as follwing
import { Input } from './ui/input'
<Input
value={previewTokenInput}
placeholder="OpenAI API key"
onChange={e => setPreviewTokenInput(e.target.value)}
/>
something confused me , the parent didn't define Ref variable, and use directly . Is this a new approach of using forwardRef ?
the codes are from https://github.com/vercel-labs/ai-chatbot,
- /component/chat.tsx
- /component/ui/input.tsx
Just because a child component forwards a React ref doesn't mean a parent component necessarily needs to pass one. React components generally ignore props they don't care about, and for those props that are not passed their values will simply be undefined or receive a default/fallback value if that is how the child component was implemented.
No, this is always how the
React.forwardReffunction worked.There is no difference between the two components in terms of "cases".
In terms of forwarding React refs, the "cases" are identical.
What is different between the two though is in the first example, the code is actually creating a ref and passing it to the
MyInputcomponent.The same could be done with the second code example: