打字稿:反应事件类型

新手上路,请多包涵

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> 似乎没有工作,因为我收到一个错误, namevaluetarget 上不存在。

非常感谢所有事件的更通用的答案。

谢谢

原文由 r.sendecky 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 680
2 个回答

SyntheticEvent 接口是通用的:

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

(从技术上讲, currentTarget 属性位于父 BaseSyntheticEvent 类型上。)

currentTarget 是通用约束和 EventTarget 的交集。

此外,由于您的事件是由输入元素引起的,您应该使用 ChangeEvent在定义文件 中, 反应文档 中)。

应该:

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

(注:此答案最初建议使用 React.FormEvent 。评论中的讨论与此建议有关,但应使用 React.ChangeEvent 如上所示。)

原文由 Nitzan Tomer 发布,翻译遵循 CC BY-SA 4.0 许可协议

问题不在于事件类型,而在于打字稿中的 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;
}

因此,EventTarget 上不存在 namevalue 是正确的。您需要做的是将目标转换为具有所需属性的特定元素类型。在这种情况下,它将是 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 文件。

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

原文由 Edwin 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题