React select ref typescript

[reactjs] How to use refs in React with Typescript

I’m using Typescript with React. I’m having trouble understanding how to use refs so as to get static typing and intellisense with respect to the react nodes referenced by the refs. My code is as follows.

import * as React from 'react'; interface AppState < count: number; >interface AppProps < steps: number; >interface AppRefs < stepInput: HTMLInputElement; >export default class TestApp extends React.Component < constructor(props: AppProps) < super(props); this.state = < count: 0 >; > incrementCounter() < this.setState(); > render() < return ( 

Hello World

Count : ); >>

This question is related to reactjs typescript

The answer is

If you’re using React 16.3+, the suggested way to create refs is using React.createRef() .

class TestApp extends React.Component < private stepInput: React.RefObject; constructor(props) < super(props); this.stepInput = React.createRef(); >render() < return />; > > 

When the component mounts, the ref attribute’s current property will be assigned to the referenced component/DOM element and assigned back to null when it unmounts. So, for example, you can access it using this.stepInput.current .

For more on RefObject , see @apieceofbart’s answer or the PR createRef() was added in.

class TestApp extends React.Component  < private stepInput: HTMLInputElement; constructor(props) < super(props); this.stepInput = null; this.setStepInputRef = element =>< this.stepInput = element; >; > render() < return /> > > 

When the component mounts, React will call the ref callback with the DOM element, and will call it with null when it unmounts. So, for example, you can access it simply using this.stepInput .

By defining the ref callback as a bound method on the class as opposed to an inline function (as in a previous version of this answer), you can avoid the callback getting called twice during updates.

There used to be an API where the ref attribute was a string (see Akshar Patel’s answer), but due to some issues, string refs are strongly discouraged and will eventually be removed.

Edited May 22, 2018 to add the new way of doing refs in React 16.3. Thanks @apieceofbart for pointing out that there was a new way.

One way (which I’ve been doing) is to setup manually :

then you can even wrap this up in a nicer getter function (e.g. here):

stepInput = (): HTMLInputElement => ReactDOM.findDOMNode(this.refs.stepInput); 

Since React 16.3 the way to add refs is to use React.createRef as Jeff Bowen pointed in his answer. However you can take advantage of Typescript to better type your ref.

In your example you’re using ref on input element. So they way I would do it is:

class SomeComponent extends React.Component < private inputRef: React.RefObject; constructor() < . this.inputRef = React.createRef(); >. render() < />; > > 

By doing this when you want to make use of that ref you have access to all input methods:

You can use it on custom components as well:

private componentRef: React.RefObject>; 

and then have, for example, access to props :

this.componentRef.current.props; // 'props' satisfy IProps interface 

React.createRef (class components)

class ClassApp extends React.Component < inputRef = React.createRef(); render() < return /> > > 

Note: Omitting the old String Refs legacy API here.

React.useRef (Hooks / function components)

const FunctionApp = () => < const inputRef = React.useRef(null) // note the passed in `null` arg return /> > 
const FunctionApp = () => < const renderCountRef = useRef(0) useEffect(() =>< renderCountRef.current += 1 >) // . other render code > 

Note: Don’t initialize useRef with null in this case. It would make the renderCountRef type readonly (see example). If you need to provide null as initial value, do this:

const renderCountRef = useRef(null) 

Callback refs (work for both)

// Function component example const FunctionApp = () => < const handleDomNodeChange = (domNode: HTMLInputElement | null) => < // . do something with changed dom node. >return /> > 

EDIT: This is no longer the right way to use refs with Typescript. Look at Jeff Bowen’s answer and upvote it to increase its visibility.

Found the answer to the problem. Use refs as below inside the class.

Thanks @basarat for pointing in the right direction.

If you’re using React.FC , add the HTMLDivElement interface:

const myRef = React.useRef(null); 

And use it like the following:

To use the callback style (https://facebook.github.io/react/docs/refs-and-the-dom.html) as recommended on React’s documentation you can add a definition for a property on the class:

export class Foo extends React.Component, <>> < // You don't need to use 'references' as the name references: < // If you are using other components be more specific than HTMLInputElement myRef: HTMLInputElement; >= < myRef: null >. myFunction() < // Use like this this.references.myRef.focus(); >. render() < return(< this.references.myRef = i; >>/>) > 

Lacking a complete example, here is my little test script for getting user input when working with React and TypeScript. Based partially on the other comments and this link https://medium.com/@basarat/strongly-typed-refs-for-react-typescript-9a07419f807#.cdrghertm

/// // Init our code using jquery on document ready $(function () < ReactDOM.render(, document.getElementById("reactTest")); >); interface IServerTimeProps < >interface IServerTimeState < time: string; >interface IServerTimeInputs < userFormat?: HTMLInputElement; >class ServerTime extends React.Component < inputs: IServerTimeInputs = <>; constructor() < super(); this.state = < time: "unknown" >> render() < return ( 
Server time: this.inputs.userFormat = a > defaultValue="s" >
); > // Update state with value from server _buttonClick(): void < alert(`Format:$`); // This part requires a listening web server to work, but alert shows the user input jQuery.ajax(< method: "POST", data: < format: this.inputs.userFormat.value >, url: "/Home/ServerTime", success: (result) => < this.setState(< time : result >); > >); >

For typescript user no constructor required.

private divRef: HTMLDivElement | null = null getDivRef = (ref: HTMLDivElement | null): void => < this.divRef = ref >render() < return /> > 

For those looking on how to do it when you have an array of elements:

const textInputRefs = useRef<(HTMLDivElement | null)[]>([]) . const onClickFocus = (event: React.BaseSyntheticEvent, index: number) => < textInputRefs.current[index]?.focus() >; . ( textInputs.current[index] = ref> /> onClickFocus(event, index)> /> > 

From React type definition

 type ReactInstance = Component | Element; . refs: < React select ref typescript: ReactInstance >; 

So you can access you refs element as follow

stepInput = () => ReactDOM.findDOMNode(this.refs['stepInput']); 

without redefinition of refs index.

As @manakor mentioned you can get error like

Property ‘stepInput’ does not exist on type ‘

if you redefine refs(depends on IDE and ts version you use)

I always do this, in that case to grab a ref

let input: HTMLInputElement = ReactDOM.findDOMNode(this.refs.input);

Just to add a different approach — you can simply cast your ref, something like:

let myInputElement: Element = this.refs["myInput"] as Element 

If you wont to forward your ref , in Props interface you need to use RefObject type from import React, < RefObject >from ‘react’;

class SelfFocusingInput extends React.Component any >, <>> < ctrls: < input?: HTMLInputElement; >= <>; render() < return ( this.ctrls.input = input> value= onChange=  < this.props.onChange(this.ctrls.input.value) >> /> ); > componentDidMount() < this.ctrls.input.focus(); >> 

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

unform / unform Public archive

How to use react-select with typescript? #226

How to use react-select with typescript? #226

Comments

I’m using the code that is in the documentation of Unform to use the react-select with tsx extension but I have a few errors that I can’t resolve for myself. It seems to me that they are typing errors.

import React, < useRef, useEffect >from "react"; import ReactSelect, < OptionTypeBase, Props as SelectProps, >from "react-select"; import < useField >from "@unform/core"; interface Props extends SelectProps  < name: string; >const Select: React.FC = (< name, . rest >) => < const selectRef = useRef(null); const < fieldName, defaultValue, registerField, error >= useField(name); useEffect(() => < registerField(< name: fieldName, ref: selectRef.current, path: "state.value", getValue: (ref: any) => < if (rest.isMulti) < if (!ref.state.value) < return []; >return ref.state.value.map((option: OptionTypeBase) => option.value); > else < if (!ref.state.value) < return ""; >return ref.state.value.value; > >, >); >, [fieldName, registerField, rest.isMulti]); return ( ref= classNamePrefix="react-select" /> ); >; export default Select; 

Argument of type ‘ < name: string; ref: null; path: string; getValue: (ref: any) =>any; >’ is not assignable to parameter of type ‘UnformField’.
Type ‘ < name: string; ref: null; path: string; getValue: (ref: any) =>any; >’ is not assignable to type ‘FunctionUnformField’.
Types of property ‘path’ are incompatible.
Type ‘string’ is not assignable to type ‘undefined’.ts(2345)

The text was updated successfully, but these errors were encountered:

Источник

Strongly Typed React Refs with TypeScript

If you’ve been working with React for some time you probably figured out that refs are very easy to start with, but rather inflexible after some point.

But anyway, refs are available and they work. So why not use them?

When working with TypeScript it’s usually a common practice to have everything as strongly typed as possible.

Unfortunately refs is typed as React select ref typescript: ReactInstance , which force us to type this.refs[«myInput] . This is definitely not what we want.

Using callback references

ref as a callback is the recommended approach on how to use it nowadays, and the solution with TypeScript is pretty simple.

import * as React from "react"; export class CustomTextInput extends React.Component<>, <>>  private textInput: HTMLInputElement; constructor()  super(); this.focus = this.focus.bind(this); > public focus()  this.textInput.focus(); > public render()  return div> input type="text" ref=<(ref) => this.textInput = ref> /> input type="button" value="Focus the text input" onClick=this.focus> /> /div>; > > export class AutoFocusTextInput extends React.Component<>, <>>  private input: CustomTextInput; constructor()  super(); > protected componentDidMount()  this.input.focus(); > public render()  return div> CustomTextInput ref=<(ref) => this.input = ref> /> /div>; > > 

This example is exactly the same as in the official ref docs. The only single difference is that we have add a typed property to our class private textInput: HTMLInputElement; . With this is now possible to safely type this.input.value , this.input.focus() , this.input.maxLength and so on, without compiler warnings.

Using string references

The string refs are eventually going to be deprecated. But in case you’re still using it and don’t want to migrate to callback references, it’s also pretty simple to add typings to it.

import * as React from "react"; export class CustomTextInput extends React.Component<>, <>>  public refs:  textInput: HTMLInputElement; >; constructor()  super(); this.focus = this.focus.bind(this); > public focus()  this.refs.textInput.focus(); > public render()  return div> input type="text" ref="textInput" /> input type="button" value="Focus the text input" onClick=this.focus> /> /div>; > > 

We’re simply overriding the refs property to be strongly typed. Yeah, that’s all.

The difference between this example and the above is that this one is using the standard React refs property while the other is defining a new one.

Whatever you prefer, just don’t forget to “type” your React components as much as possible.

Aptakube is a modern, lightweight and multi-cluster Kubernetes desktop client.
Available on Windows, macOS and Linux. Learn more →

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

unform / unform Public archive

How to use react-select with typescript? #226

How to use react-select with typescript? #226

Comments

I’m using the code that is in the documentation of Unform to use the react-select with tsx extension but I have a few errors that I can’t resolve for myself. It seems to me that they are typing errors.

import React, < useRef, useEffect >from "react"; import ReactSelect, < OptionTypeBase, Props as SelectProps, >from "react-select"; import < useField >from "@unform/core"; interface Props extends SelectProps  < name: string; >const Select: React.FC = (< name, . rest >) => < const selectRef = useRef(null); const < fieldName, defaultValue, registerField, error >= useField(name); useEffect(() => < registerField(< name: fieldName, ref: selectRef.current, path: "state.value", getValue: (ref: any) => < if (rest.isMulti) < if (!ref.state.value) < return []; >return ref.state.value.map((option: OptionTypeBase) => option.value); > else < if (!ref.state.value) < return ""; >return ref.state.value.value; > >, >); >, [fieldName, registerField, rest.isMulti]); return ( ref= classNamePrefix="react-select" /> ); >; export default Select; 

Argument of type ‘ < name: string; ref: null; path: string; getValue: (ref: any) =>any; >’ is not assignable to parameter of type ‘UnformField’.
Type ‘ < name: string; ref: null; path: string; getValue: (ref: any) =>any; >’ is not assignable to type ‘FunctionUnformField’.
Types of property ‘path’ are incompatible.
Type ‘string’ is not assignable to type ‘undefined’.ts(2345)

The text was updated successfully, but these errors were encountered:

Источник

Читайте также:  Read file with readline python
Оцените статью