Typescript input onchange event.target.value

472,253

Solution 1

Generally event handlers should use e.currentTarget.value, e.g.:

onChange = (e: React.FormEvent<HTMLInputElement>) => {
    const newValue = e.currentTarget.value;
}

You can read why it so here (Revert "Make SyntheticEvent.target generic, not SyntheticEvent.currentTarget.").

UPD: As mentioned by @roger-gusmao ChangeEvent more suitable for typing form events.

onChange = (e: React.ChangeEvent<HTMLInputElement>)=> {
   const newValue = e.target.value;
}

Solution 2

the correct way to use in TypeScript is

  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // No longer need to cast to any - hooray for react!
    this.setState({temperature: e.target.value});
  }

  render() {
        ...
        <input value={temperature} onChange={this.handleChange} />
        ...
    );
  }

Follow the complete class, it's better to understand:

import * as React from "react";

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};


interface TemperatureState {
   temperature: string;
}

interface TemperatureProps {
   scale: string;

}

class TemperatureInput extends React.Component<TemperatureProps, TemperatureState> {
  constructor(props: TemperatureProps) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  //  handleChange(e: { target: { value: string; }; }) {
  //    this.setState({temperature: e.target.value});  
  //  }


  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // No longer need to cast to any - hooray for react!
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature} onChange={this.handleChange} />
      </fieldset>
    );
  }
}

export default TemperatureInput;

Solution 3

You can do the following:

import { ChangeEvent } from 'react';

const onChange = (e: ChangeEvent<HTMLInputElement>)=> {
   const newValue = e.target.value;
}

Solution 4

as HTMLInputElement works for me

Solution 5

we can also use the onChange event fire-up with defined types(in functional component) like as follows:

 const handleChange = (
    e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
  ) => {
        const name = e.target.name;
        const value = e.target.value;
};

Share:
472,253

Related videos on Youtube

wildeyes
Author by

wildeyes

Looking for freelance work, contact me.

Updated on April 26, 2022

Comments

  • wildeyes
    wildeyes about 2 years

    In my react and typescript app, I use:

    onChange={(e) => data.motto = (e.target as any).value}
    

    How do I correctly define the typings for the class, so I wouldn't have to hack my way around the type system with any?

    export interface InputProps extends React.HTMLProps<Input> {
    ...
    
    }
    
    export class Input extends React.Component<InputProps, {}> {
    }
    

    If I put target: { value: string }; I get :

    ERROR in [default] /react-onsenui.d.ts:87:18
    Interface 'InputProps' incorrectly extends interface 'HTMLProps<Input>'.
      Types of property 'target' are incompatible.
        Type '{ value: string; }' is not assignable to type 'string'.
    
  • tocqueville
    tocqueville about 7 years
    This simply does not work. value is not a property of the interface EventTarget
  • Yozi
    Yozi about 7 years
    Of course not EventTarget, but part of HTMLInputElement You can see full definition here github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types‌​/…
  • tocqueville
    tocqueville about 7 years
    Oh sorry, you used currentTarget. In that case yes, it works, but the question was about target
  • Yozi
    Yozi about 7 years
    Yes, you right, but as mentioned in github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 using target incorrect in most cases. Moreover, target does not have T to force us to write correctly
  • Roger Gusmao
    Roger Gusmao about 6 years
    The value type is not string!
  • James Conkling
    James Conkling almost 6 years
    note: to ensure types are available, add lib: ["dom"] to compilerOptions in tsconfig.json
  • Oblivionkey3
    Oblivionkey3 over 5 years
    This didn't work for me, I had to cast the event to React.ChangeEvent<HTMLInputElement> rather than a FormEvent.
  • Alexandre Rivest
    Alexandre Rivest about 5 years
    @JamesConkling Thank you so much!
  • Trevor Wood
    Trevor Wood about 5 years
    And if you have multiple inputs do you need to make a row for each?
  • tlavarea
    tlavarea over 4 years
    Another way to make sure 'this' is assigned appropriately in the handleChange function would be to write handleChange as an arrow function i.e. handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.setState(...); }; By doing that, one would no longer have to use the constructor to bind the handleEvent function.
  • tlavarea
    tlavarea over 4 years
    One more way to handle 'this' instead of using the constructor and bind method would be to use the arrow function in the onChange prop i.e. onChange={e => this.handleChange(e)}
  • Sagar
    Sagar about 4 years
    With these changes I am getting error: No overload matches this call. Overload 1 of 2, '(props: Readonly<Props>): Input', gave the following error. Type '(e: ChangeEvent<HTMLInputElement>) => void' is not assignable to type '(event: CustomEvent<ChangeDetail>) => void'. Can someone please help me?
  • httpete
    httpete over 3 years
    I found this worked in later versions of react: React.ChangeEventHandler<HTMLInputElement>
  • Oversteer
    Oversteer over 3 years
    tiny edit remove extraneous parentheses - const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>): void => {
  • AO19
    AO19 over 3 years
    Finally something worked. I still don't understand how a ChangeEvent<HTMLInputElement> does not have a value on currentTarger or target...
  • J86
    J86 almost 3 years
    That doesn't have a .target?
  • Zahra Shahrouzi
    Zahra Shahrouzi over 2 years
    by using e.target.value ,only ChangeEvent works
  • WebWanderer
    WebWanderer over 2 years
    This is a great answer that works across the board. I was heavy on Angular, was forced onto React for a year, and am now playing with Angular again to stay fresh on it. React provides some really nice event interfaces that Typescript natively lacks. This approach helps get the same desired typing, even in vanilla. Thanks.