typescript: ตอบสนองประเภทเหตุการณ์


131

ประเภทที่ถูกต้องสำหรับเหตุการณ์ React คืออะไร เริ่มแรกฉันแค่ใช้anyเพื่อความเรียบง่าย ตอนนี้ฉันกำลังพยายามทำความสะอาดและหลีกเลี่ยงการใช้anyอย่างสมบูรณ์

ดังนั้นในรูปแบบง่ายๆดังนี้:

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>
    )
  }
}

ประเภทใดที่ฉันใช้ที่นี่เป็นประเภทเหตุการณ์

React.SyntheticEvent<EventTarget>ดูเหมือนจะไม่ได้ร่วมงานที่ฉันได้รับข้อผิดพลาดที่nameและไม่อยู่ในvaluetarget

คำตอบทั่วไปเพิ่มเติมสำหรับทุกเหตุการณ์จะได้รับการชื่นชมจริงๆ

ขอบคุณ

คำตอบ:


148

SyntheticEventอินเตอร์เฟซทั่วไป:

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

และcurrentTargetจุดตัดของข้อ จำกัด ทั่วไปและ EventTarget.
นอกจากนี้เนื่องจากเหตุการณ์ของคุณเกิดจากองค์ประกอบอินพุตคุณควรใช้FormEvent( in definition file , react docs )

ควรจะเป็น:

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

15
อะไรคือจุดที่ดีในการอ่านเกี่ยวกับประเภทเหตุการณ์ทั่วไปทั้งหมด? ไม่สามารถหาได้จากที่ไหน
r.sendecky

3
ตอบสนองประเภทเหตุการณ์? พวกเขาจะมีคำอธิบายทั้งหมดในหน้าเหตุการณ์ในเอกสาร
Nitzan Tomer

3
ฉันได้รับ 'ชื่อ' ไม่มีอยู่ในประเภท 'EventTarget & HTMLInputElements' (TS v2.4)
Falieson

4
สิ่งนี้ยังคงทำให้ฉันมีข้อผิดพลาดต่อไปนี้ "คุณสมบัติ" ค่า "ไม่มีอยู่ในประเภท" EventTarget & HTMLInputElement ""
tomhughes

1
@CMCDragonkai ฉันคิดว่าe.keyเป็นเพียงส่วนหนึ่งของเหตุการณ์บนคีย์บอร์ด
Nitzan Tomer

32

ปัญหาไม่ได้อยู่ที่ประเภทเหตุการณ์ แต่อินเทอร์เฟซ EventTarget ใน typescript มีเพียง 3 วิธี:

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;
}

ดังนั้นจึงถูกต้องnameและvalueไม่มีอยู่ใน EventTarget สิ่งที่คุณต้องทำคือโยนเป้าหมายไปยังประเภทองค์ประกอบที่เฉพาะเจาะจงด้วยคุณสมบัติที่คุณต้องการ HTMLInputElementในกรณีนี้ก็จะเป็น

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

นอกจากนี้สำหรับเหตุการณ์ที่เกิดขึ้นแทนการ React.SyntheticEvent คุณยังสามารถพิมพ์ดังต่อไปนี้: Event, MouseEvent, KeyboardEvent... ฯลฯ ขึ้นอยู่กับกรณีการใช้งานของตัวจัดการ

วิธีที่ดีที่สุดในการดูคำจำกัดความประเภททั้งหมดนี้คือการชำระเงินไฟล์. d.ts จากทั้ง typescript & react

ตรวจสอบลิงก์ต่อไปนี้เพื่อดูคำอธิบายเพิ่มเติม เหตุใด Event.target จึงไม่ใช่ Element ใน typescript


2
PS ดูเหมือนว่าไฟล์นิยามประเภทของฉันจะล้าสมัยไปหน่อยเนื่องจากไม่แสดงอินเทอร์เฟซ SyntheticEvent <T> ทั่วไป คำตอบจาก Nitzan Tomer ดีกว่า
Edwin

ใช่คำตอบของ Nitzan ดูเหมือนจะสะอาดกว่า ขอบคุณสำหรับความพยายาม
r.sendecky

26

เพื่อรวมคำตอบของ Nitzan และ Edwin เข้าด้วยกันฉันพบว่าสิ่งนี้เหมาะกับฉัน:

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; ??? คุณกำลังเปลี่ยนอุปกรณ์ประกอบฉาก: o
Marwen Trabelsi

เพียงคัดลอกบรรทัดจากคำถามเดิมเพื่อให้คำตอบเหมาะสมกับ OP
จาม

21

ฉันคิดว่าวิธีที่ง่ายที่สุดคือ:

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();
}

สิ่งนี้ทำเพื่อฉัน
Benyam Ephrem

1
.ChangeEventเป็นกุญแจสำคัญสำหรับฉัน
Skyy2010

4

คุณสามารถทำเช่นนี้ในปฏิกิริยา

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
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.