Typescript input onchange event.target.value


144

Benim tepki ve daktilo uygulamasında, ben kullanın: onChange={(e) => data.motto = (e.target as any).value}.

Sınıf için yazımları nasıl doğru bir şekilde tanımlarım, böylelikle yazım sisteminde yolumu kesmek zorunda kalmazdım any?

export interface InputProps extends React.HTMLProps<Input> {
...

}

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

Eğer koyarsam target: { value: string };alırım:

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'.

Yanıtlar:


244

Genellikle olay işleyicileri e.currentTarget.value, örneğin şunları kullanmalıdır :

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

Neden böyle olduğunu buradan okuyabilirsiniz ( "Make SyntheticEvent.target, SyntheticEvent.currentTarget'i değil jenerik yap." ).

UPD: @ roger-gusmao'da belirtildiği gibi, ChangeEventform olaylarını yazmak için daha uygundur.

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

17
Bu sadece işe yaramıyor. değer, EventTarget arayüzünün bir özelliği değil
tocqueville

1
Elbette EventTarget değil, HTMLInputElement'in bir parçası Tam tanımı burada görebilirsiniz github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/…
Yozi

1
Üzgünüm kullandın currentTarget. Bu durumda evet, işe yarıyor, ancak soru şuydutarget
tocqueville

1
Evet, haklısınız, ancak github.com/DefinitelyTyped/DefinitelyTyped/pull/12239'da belirtildiği gibi targetçoğu durumda yanlış kullanıyorsunuz . Dahası, hedefin Tbizi doğru yazmaya
zorlaması gerekmez

1
Bu benim için işe yaramadı, olayı React.ChangeEvent<HTMLInputElement>bir FormEvent yerine yayınlamak zorunda kaldım.
Oblivionkey3

86

TypeScript'te kullanmanın doğru yolu

  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} />
        ...
    );
  }

Tüm dersi takip edin, anlamak daha iyidir:

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;

3
not:, türleri mevcuttur sağlamak eklemek lib: ["dom"]için compilerOptionsdetsconfig.json
James Conkling

1
@JamesConkling Çok teşekkür ederim!
Alexandre Rivest

1
Birden fazla girişiniz varsa, her biri için bir satır oluşturmanız gerekir mi?
Trevor Wood

'This' öğesinin handleChange işlevinde uygun şekilde atandığından emin olmanın başka bir yolu, handleChange'i bir ok işlevi olarak yazmaktır, yani handleChange = (e: React.ChangeEvent <HTMLInputElement>) => {this.setState (...); }; Bunu yaparak, artık handleEvent işlevini bağlamak için yapıcıyı kullanmak zorunda kalmayacaksınız.
tlavarea

Yapıcı ve bağlama yöntemini kullanmak yerine 'bunu' işlemenin bir başka yolu, onChange propundaki ok işlevini kullanmaktır, yani onChange = {e => this.handleChange (e)}
tlavarea

12

as HTMLInputElement benim için çalışıyor


9

targetEğer eklemek çalıştı InputPropsaynı değildir targetiçinde olan istediğiniReact.FormEvent

Bu nedenle, bulabileceğim çözüm, olayla ilgili türleri, hedef türünüzü eklemek için genişletmek oldu:

interface MyEventTarget extends EventTarget {
    value: string
}

interface MyFormEvent<T> extends React.FormEvent<T> {
    target: MyEventTarget
}

interface InputProps extends React.HTMLProps<Input> {
    onChange?: React.EventHandler<MyFormEvent<Input>>;
}

Bu sınıflara sahip olduğunuzda, giriş bileşeninizi şu şekilde kullanabilirsiniz:

<Input onChange={e => alert(e.target.value)} />

derleme hataları olmadan. Aslında yukarıdaki ilk iki arayüzü diğer bileşenleriniz için de kullanabilirsiniz.


Değer türü dize değil!
Roger Gusmao

7

şanslıyım bir çözüm buldum. yapabilirsin

{ChangeEvent} 'react'ten içe aktar;

ve sonra şu şekilde kod yazın: e:ChangeEvent<HTMLInputElement>


2

İşte ES6 nesne imhası ile TS 3.3 ile test edilen bir yol.
Bu örnek, bir metin girişi içindir.

name: string = '';

private updateName({ target }: { target: HTMLInputElement }) {
    this.name = target.value;
}

1

Bu, bir FileListNesne ile çalıştığınız zamandır:

onChange={(event: React.ChangeEvent<HTMLInputElement>): void => {
  const fileListObj: FileList | null = event.target.files;
  if (Object.keys(fileListObj as Object).length > 3) {
    alert('Only three images pleaseeeee :)');
  } else {
    // Do something
  }

  return;
}}

1
  function handle_change(
    evt: React.ChangeEvent<HTMLInputElement>
  ): string {
    evt.persist(); // This is needed so you can actually get the currentTarget
    const inputValue = evt.currentTarget.value;

    return inputValue
  }

Ve emin olun olun "lib": ["dom"]Gözlerinde farklı tsconfig.


1

Alt Bileşeni kullanırken, türü şu şekilde kontrol ederiz.

Ana Bileşen:

export default () => {

  const onChangeHandler = ((e: React.ChangeEvent<HTMLInputElement>): void => {
    console.log(e.currentTarget.value)
  }

  return (
    <div>
      <Input onChange={onChangeHandler} />
    </div>
  );
}

Alt Bileşen:

type Props = {
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
}

export Input:React.FC<Props> ({onChange}) => (
  <input type="tex" onChange={onChange} />
)

0

Henüz bahsedilmeyen bir alternatif, aldığı props yerine onChange işlevini yazmaktır. React.ChangeEventHandler'ı kullanma:

const stateChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
    console.log(event.target.value);
};

-1

Teşekkürler @haind

Evet HTMLInputElement, giriş alanı için çalıştı

//Example
var elem = e.currentTarget as HTMLInputElement;
elem.setAttribute('my-attribute','my value');
elem.value='5';

Bu HTMLInputElementarayüz gelen devralır olmasıdır HTMLElementmiras olan EventTargetkök seviyesinde. Bu nedenle kullanarak iddia edebilir asbu durumda kullandığımız gibi bağlama göre belirli arayüzleri kullanımı operatörü HTMLInputElementdiğer arayüzleri olabilir giriş alanı için HTMLButtonElement, HTMLImageElementvs.

https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement

Daha fazla referans için diğer mevcut arayüzleri buradan kontrol edebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.