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.