Reputation: 2608
I'm just play around with typescript and I've got problem to use useRef in a custom element
passing it as prop
I've tried with
import React from "react";
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {
ref: HTMLElement | null
}
const Input: React.FC<InputProps> = ({ ...inputProps }) => {
return (
<input
className="px-2 py-1 text-gray-700 text-2xl bg-white border-2 border-gray-200 hover:border-purple-300 focus:outline-none focus:bg-white rounded-l-lg shadow-md"
{...inputProps}
/>
);
};
export default Input;
import React, { useRef } from "react";
import Input from "./input";
import Button from "./button";
const Form: React.FC = () => {
const todoRef = useRef<HTMLElement | null>(null);
return (
<form onSubmit={}>
<Input type="text" id="todo" ref={todoRef}/>
<Button type="submit">+</Button>
</form>
);
};
export default Form;
What's the right way, please?
I worked out with: https://codesandbox.io/s/typescript-useref-example-e0hc4
Upvotes: 7
Views: 17031
Reputation: 2964
You need to use React.forwardRef
on the component you are passing the ref to, like so:
const Input = React.forwardRef<HTMLElement, InputProps>(({ ...inputProps }, ref) => {
return (
<input
ref={ref}
className="px-2 py-1 text-gray-700 text-2xl bg-white border-2 border-gray-200 hover:border-purple-300 focus:outline-none focus:bg-white rounded-l-lg shadow-md"
{...inputProps}
/>
);
});
Refs are treated differently than normal props. They are not included in the props
object. To expose a ref inside a custom component you have to use forwardRef
. Once the ref is exposed inside your component, you should assign it to one of the components in your return statement (usually the top level component, input
in this case).
UPDATE:
If you're seeing the error React.HTMLElement is not assignable to type React.HTMLInputElement
you should change the type of ref that you're creating to the appropriate one:
const todoRef = useRef<HTMLInputElement | null>(null)
and in the input component change the first line to:
const Input = React.forwardRef<HTMLInputElement, InputProps>(({ ...inputProps }, ref) => {
Upvotes: 3
Reputation: 1985
change to:
const Input: React.FC<InputProps> = React.forwardRef((inputProps, ref) => {
return(
<input
className="px-2 py-1 text-gray-700 text-2xl bg-white border-2 border-gray-200 hover:border-purple-300 focus:outline-none focus:bg-white rounded-l-lg shadow-md"
ref={ref}
{...inputProps}
/>
)
})
export default Input;
output here: https://codesandbox.io/s/typescript-useref-example-p3hh4
Upvotes: 1
Reputation: 1039
Try one of this:
<Input type="text" id="todo" ref={todoRef as any}/>
Upvotes: -2