Typecript: Các loại sự kiện phản ứng


130

Loại chính xác cho các sự kiện React là gì. Ban đầu tôi chỉ sử dụng anyvì mục đích đơn giản. Bây giờ, tôi đang cố gắng dọn dẹp mọi thứ và tránh sử dụng anyhoàn toàn.

Vì vậy, trong một hình thức đơn giản như sau:

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

Tôi sử dụng loại nào ở đây làm loại sự kiện?

React.SyntheticEvent<EventTarget>dường như không hoạt động vì tôi gặp lỗi namevaluekhông tồn tại trên target.

Câu trả lời tổng quát hơn cho tất cả các sự kiện sẽ thực sự được đánh giá cao.

Cảm ơn

Câu trả lời:


146

Các SyntheticEvent giao diện là chung chung:

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

currentTargetlà một giao điểm của ràng buộc chung và EventTarget.
Ngoài ra, vì các sự kiện của bạn là do yếu tố đầu vào gây ra, bạn nên sử dụng FormEvent( trong tệp định nghĩa , tài liệu phản ứng ).

Nên là:

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

15
Nơi tốt để đọc về tất cả các loại sự kiện phổ biến là gì? Không thể tìm thấy ở bất cứ đâu.
r.sendecky

3
Phản ứng các loại sự kiện? Tất cả chúng đều được mô tả trong trang sự kiện trong tài liệu .
Nitzan Tomer

3
Tôi nhận được 'tên' không tồn tại trên loại 'EventTarget & HTMLInputElements' (TS v2.4)
Falieson

4
Điều này vẫn mang lại cho tôi lỗi sau. "Giá trị thuộc tính" không tồn tại trên loại 'EventTarget & HTMLInputElement'. "
tomhughes

1
@CMCDragonkai Tôi nghĩ đó e.keychỉ là một phần của các sự kiện bàn phím.
Nitzan Tomer

30

Vấn đề không phải ở loại Sự kiện, mà là giao diện EventTarget trong bản định kiểu chỉ có 3 phương thức:

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

Vì vậy, nó là chính xác namevaluekhông tồn tại trên EventTarget. Những gì bạn cần làm là truyền mục tiêu đến loại phần tử cụ thể với các thuộc tính bạn cần. Trong trường hợp này, nó sẽ là HTMLInputElement.

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

Ngoài ra cho các sự kiện thay vì React.SyntheticEvent, bạn cũng có thể gõ như sau: Event, MouseEvent, KeyboardEvent... vv, phụ thuộc vào các trường hợp sử dụng các trình điều khiển.

Cách tốt nhất để xem tất cả các định nghĩa loại này là kiểm tra các tệp .d.ts từ cả hai loại chỉ định và phản ứng.

Ngoài ra, hãy xem liên kết sau để biết thêm giải thích: Tại sao Event.target không phải là Element trong Typescript?


2
ps. Có vẻ như tệp định nghĩa kiểu của tôi hơi lỗi thời vì nó không hiển thị giao diện SyntheticEvent <T> chung. Câu trả lời từ Nitzan Tomer là tốt hơn.
Edwin

Vâng, câu trả lời của Nitzan có vẻ gọn gàng hơn. Cảm ơn cho những nỗ lực.
r.sendecky

26

Để kết hợp cả hai câu trả lời của Nitzan và Edwin, tôi thấy rằng một cái gì đó như thế này phù hợp với tôi:

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; ??? bạn đang thay đổi đạo cụ: o
Marwen Trabelsi

Chỉ cần sao chép dòng từ câu hỏi ban đầu để câu trả lời có ý nghĩa với OP.
cham

21

Tôi nghĩ cách đơn giản nhất là:

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

Điều này đã làm điều đó cho tôi.
Benyam Ephrem

1
.ChangeEventlà chìa khóa cho tôi
Skyy2010

4

bạn có thể làm như thế này trong phản ứng

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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.