Typescript: React olay türleri


131

React olayları için doğru tür nedir? Başlangıçta anybasitlik uğruna kullandım . Şimdi, bir şeyleri temizlemeye ve kullanmaktan anytamamen kaçınmaya çalışıyorum .

Yani bunun gibi basit bir biçimde:

export interface LoginProps {
  login: {
    [k: string]: string | Function
    uname: string
    passw: string
    logIn: Function
  }
}
@inject('login') @observer
export class Login extends Component<LoginProps, {}> {
  update = (e: React.SyntheticEvent<EventTarget>): void => {
    this.props.login[e.target.name] = e.target.value
  }
  submit = (e: any): void => {
    this.props.login.logIn()
    e.preventDefault()
  }
  render() {
    const { uname, passw } = this.props.login
    return (
      <div id='login' >
        <form>
          <input
            placeholder='Username'
            type="text"
            name='uname'
            value={uname}
            onChange={this.update}
          />
          <input
            placeholder='Password'
            type="password"
            name='passw'
            value={passw}
            onChange={this.update}
          />
          <button type="submit" onClick={this.submit} >
            Submit
          </button>
        </form>
      </div>
    )
  }
}

Burada olay türü olarak ne tür kullanıyorum?

React.SyntheticEvent<EventTarget>Bir hata aldığım nameve valueüzerinde bulunmadığım için çalışmıyor gibi görünüyor target.

Tüm olaylar için daha genel bir cevap gerçekten takdir edilecektir.

Teşekkürler

Yanıtlar:


148

SyntheticEvent arayüzü geneldir:

interface SyntheticEvent<T> {
    ...
    currentTarget: EventTarget & T;
    ...
}

Ve currentTargetjenerik kısıtlamanın kesişimidir ve EventTarget.
Ayrıca, etkinliklerinize bir girdi öğesi neden olduğu için FormEvent( tanım dosyasında , tepki belgelerini ) kullanmanız gerekir.

Olmalı:

update = (e: React.FormEvent<HTMLInputElement>): void => {
    this.props.login[e.currentTarget.name] = e.currentTarget.value
}

15
Tüm yaygın olay türleri hakkında okumak için iyi bir yer neresidir? Hiçbir yerde bulunamıyor.
r.sendecky

3
React olay türleri? Hepsi dokümanlardaki olaylar sayfasında açıklanmıştır .
Nitzan Tomer

3
'EventTarget & HTMLInputElements' türünde 'ad' mevcut değil (TS v2.4)
Falieson

4
Bu hala bana şu hatayı veriyor. "Özellik 'değeri', 'EventTarget & HTMLInputElement' türünde mevcut değil."
tomhughes

1
@CMCDragonkai Bunun e.keyklavye olaylarının sadece bir parçası olduğunu düşünüyorum .
Nitzan Tomer

32

Sorun, Olay türünde değil, typecript'teki EventTarget arayüzünde yalnızca 3 yönteme sahip olmasıdır:

interface EventTarget {
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
    dispatchEvent(evt: Event): boolean;
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}

interface SyntheticEvent {
    bubbles: boolean;
    cancelable: boolean;
    currentTarget: EventTarget;
    defaultPrevented: boolean;
    eventPhase: number;
    isTrusted: boolean;
    nativeEvent: Event;
    preventDefault(): void;
    stopPropagation(): void;
    target: EventTarget;
    timeStamp: Date;
    type: string;
}

Yani bu doğrudur nameve valueEventTarget'ta yok. Yapmanız gereken şey, hedefi ihtiyaç duyduğunuz özelliklerle belirli öğe türüne çevirmektir. Bu durumda olacak HTMLInputElement.

update = (e: React.SyntheticEvent): void => {
    let target = e.target as HTMLInputElement;
    this.props.login[target.name] = target.value;
}

Aşağıdaki olarak da yerine React.SyntheticEvent olayları için, ayrıca bunları yazabilirsiniz: Event, MouseEvent, KeyboardEvent... vb, işleyici kullanımı duruma göre değişir.

Tüm bu tür tanımlarını görmenin en iyi yolu, .d.ts dosyalarını hem typcript hem de react'ten almaktır.

Ayrıca daha fazla açıklama için aşağıdaki bağlantıya bakın: Event.target neden Typescript'te Öğe Değil?


2
ps. Genel SyntheticEvent <T> arayüzünü göstermediği için tür tanımlama dosyam biraz eski gibi görünüyor. Nitzan Tomer'in cevabı daha iyi.
Edwin

Evet, Nitzan'ın cevabı daha temiz görünüyor. Çaba için teşekkürler.
r.sendecky

26

Hem Nitzan'ın hem de Edwin'in cevaplarını birleştirmek için, bunun benim için işe yaradığını buldum:

update = (e: React.FormEvent<EventTarget>): void => {
    let target = e.target as HTMLInputElement;
    this.props.login[target.name] = target.value;
}

1
this.props.login [target.name] = target.value; ??? sahne değiştiriyor musunuz: o
Marwen Trabelsi

Cevabın OP için anlamlı olması için orijinal sorudaki satırı kopyalamanız yeterli.
cham

21

Bence en basit yol şudur:

type InputEvent = React.ChangeEvent<HTMLInputElement>;
type ButtonEvent = React.MouseEvent<HTMLButtonElement>;

update = (e: InputEvent): void => this.props.login[e.target.name] = e.target.value;
submit = (e:  ButtonEvent): void => {
    this.props.login.logIn();
    e.preventDefault();
}

Bu benim için yaptı.
Benyam Ephrem

1
.ChangeEventbenim için anahtar
buydu

4

tepki olarak bunu yapabilirsin

handleEvent = (e: React.SyntheticEvent<EventTarget>) => {
  const simpleInput = (e.target as HTMLInputElement).value;
  //for simple html input values
  const formInput = (e.target as HTMLFormElement).files[0];
  //for html form elements
}
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.