简体   繁体   中英

React typescript how to use useRef as prop

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?

UPDATE

I worked out with: https://codesandbox.io/s/typescript-useref-example-e0hc4

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) => {

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

Try one of this:

  1. Use HTMLInputElement instead of HTMLElement
  2. <Input type="text" id="todo" ref={todoRef as any}/>
  3. Wrap the HTMLElement type into a ReactElement generic type

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM