Javascript 打字稿:反应事件类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42081549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:53:00  来源:igfitidea点击:

Typescript: React event types

javascriptreactjstypescript

提问by r.sendecky

What is the correct type for React events. Initially I just used anyfor the sake of simplicity. Now, I am trying to clean things up and avoid use of anycompletely.

React 事件的正确类型是什么。最初我只是any为了简单而使用。现在,我正在尝试清理东西并any完全避免使用。

So in a simple form like this:

所以以这样的简单形式:

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

What type do I use here as event type?

我在这里使用什么类型作为事件类型?

React.SyntheticEvent<EventTarget>does not seem to be working as I get an error that nameand valuedo not exist on target.

React.SyntheticEvent<EventTarget>似乎没有工作,因为我收到一个错误,name并且valuetarget.

More generalised answer for all events would be really appreciated.

对所有事件的更概括的答案将不胜感激。

Thanks

谢谢

回答by Nitzan Tomer

The SyntheticEventinterface is generic:

SyntheticEvent接口是通用的:

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

And the currentTargetis an intersection of the generic constraint and EventTarget.
Also, since your events are caused by an input element you should use the FormEvent(in definition file, the react docs).

而且currentTarget是通用约束和的交集 EventTarget
此外,由于您的事件是由输入元素引起的,您应该使用FormEvent在定义文件中react 文档)。

Should be:

应该:

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

回答by Edwin

The problem is not with the Event type, but that the EventTarget interface in typescript only has 3 methods:

问题不在于 Event 类型,而在于 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;
}

So it is correct that nameand valuedon't exist on EventTarget. What you need to do is to cast the target to the specific element type with the properties you need. In this case it will be HTMLInputElement.

所以这是正确的,name并且value在 EventTarget 上不存在。您需要做的是将目标转换为具有您需要的属性的特定元素类型。在这种情况下,它将是HTMLInputElement.

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

Also for events instead of React.SyntheticEvent, you can also type them as following: Event, MouseEvent, KeyboardEvent...etc, depends on the use case of the handler.

同样对于事件而不是 React.SyntheticEvent,您还可以按如下方式键入它们:Event, MouseEvent, KeyboardEvent...等,取决于处理程序的用例。

The best way to see all these type definitions is to checkout the .d.ts files from both typescript & react.

查看所有这些类型定义的最佳方法是从 typescript 和 react 中检出 .d.ts 文件。

Also check out the following link for more explanations: Why is Event.target not Element in Typescript?

另请查看以下链接以获取更多解释: Why is Event.target not Element in Typescript?

回答by cham

To combine both Nitzan's and Edwin's answers, I found that something like this works for me:

为了结合 Nitzan 和 Edwin 的答案,我发现这样的事情对我有用:

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

回答by Serg The Bright

I think the simplest way is that:

我认为最简单的方法是:

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

回答by Chandan Kumar

you can do like this in react

你可以在反应中这样做

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
}