打字稿:反应事件类型

时间:2017-02-07 04:06:55

标签: javascript reactjs typescript

React事件的正确类型是什么。最初我只是为了简单起见而使用from __future__ import absolute_import 。现在,我正在努力清理并避免完全使用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>namevalue不存在的错误。

非常感谢所有活动的更广泛的答案。

由于

8 个答案:

答案 0 :(得分:84)

SyntheticEvent界面是通用的:

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

currentTarget是通用约束和EventTarget的交集 此外,由于您的事件是由输入元素引起的,因此您应使用FormEventin definition filethe react docs)。

应该是:

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

答案 1 :(得分:15)

问题不在于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;
}

因此,namevalue在EventTarget上不存在是正确的。您需要做的是将目标强制转换为具有所需属性的特定元素类型。在这种情况下,它将是HTMLInputElement

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

对于事件而不是React.SyntheticEvent,您也可以按以下方式键入它们:EventMouseEventKeyboardEvent ...等等,取决于处理程序的用例

查看所有这些类型定义的最佳方法是从两个打字稿和文件中检出.d.ts文件。反应。

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

答案 2 :(得分:13)

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

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

答案 3 :(得分:6)

我认为最简单的方法是:

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

答案 4 :(得分:1)

您可以在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
}

答案 5 :(得分:1)

对于那些正在寻找一种解决方案来获取事件并在useState上存储一些内容(在我的情况下为HTML 5元素)的人,这是我的解决方案:

const [anchorElement, setAnchorElement] = useState<HTMLButtonElement | null>(null);

const handleMenu = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) : void => {
    setAnchorElement(event.currentTarget);
};

答案 6 :(得分:1)

我在types.ts文件中具有以下内容,用于html输入,选择和文本区域:

export type InputChangeEventHandler = React.ChangeEventHandler<HTMLInputElement>
export type TextareaChangeEventHandler = React.ChangeEventHandler<HTMLTextAreaElement>
export type SelectChangeEventHandler = React.ChangeEventHandler<HTMLSelectElement>

然后导入它们:

import { InputChangeEventHandler } from '../types'

然后使用它们:


const updateName: InputChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
const updateBio: TextareaChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
const updateSize: SelectChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}

然后将功能应用于您的标记(将...替换为其他必要的道具):

<input onChange={updateName} ... />
<textarea onChange={updateName} ... />
<select onChange={updateSize} ... >
  // ...
</select>

答案 7 :(得分:1)

以获取更新:event: React.ChangeEvent 提交:event: React.FormEvent 点击:event: React.MouseEvent

相关问题