Typescript : 반응 이벤트 유형


130

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그리고 value에 존재하지 않는다 target.

모든 이벤트에 대해 더 일반적인 답변을 주시면 감사하겠습니다.

감사

답변:


146

SyntheticEvent의 인터페이스는 일반적인 것입니다 :

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

그리고는 currentTarget일반 제약 조건과 EventTarget.
당신의 이벤트가 입력 요소에 의해 발생되기 때문에 또한, 당신은 사용해야합니다 FormEvent( 의 정의 파일을 , 는 문서를 반응 ).

해야한다:

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) 유형에 'name'이 존재하지 않습니다
Falieson

4
이것은 여전히 ​​다음과 같은 오류를 제공합니다. " 'EventTarget & HTMLInputElement'유형에 'value'속성이 없습니다."
tomhughes

1
@CMCDragonkai e.key키보드 이벤트의 일부일 뿐이라고 생각 합니다.
Nitzan Tomer

30

문제는 이벤트 유형이 아니라 typescript의 EventTarget 인터페이스에 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;
}

그래서 그 정확 namevalue의 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... 등, 핸들러의 사용 사례에 따라 달라집니다.

이러한 모든 유형 정의를 보는 가장 좋은 방법은 typescript 및 react 모두에서 .d.ts 파일을 체크 아웃하는 것입니다.

자세한 설명은 다음 링크를 확인하십시오. Event.target이 Typescript의 요소가 아닌 이유는 무엇입니까?


2
추신. 내 유형 정의 파일이 일반 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에 의미가 있도록합니다.
cham

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.