React事件的正确类型是什么?

最初为了简单起见,我只是使用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>
    )
  }
}

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

反应。SyntheticEvent<EventTarget>似乎不工作,因为我得到一个错误,名称和值在目标上不存在。

对所有事件的更普遍的答案将真的很感激。

谢谢


当前回答

结合Nitzan和Edwin的回答,我发现这样的东西对我很有用:

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

其他回答

SyntheticEvent接口是通用的:

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

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

currentTarget是泛型约束和EventTarget的交集。 此外,由于你的事件是由输入元素引起的,你应该使用ChangeEvent(在定义文件中,react文档)。

应该是:

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

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

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

因此,name和value在EventTarget上不存在是正确的。您需要做的是将目标转换为具有所需属性的特定元素类型。在本例中,它将是HTMLInputElement。

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

同样适用于事件而不是React。synticevent,你也可以输入如下:Event, MouseEvent, KeyboardEvent…等等,取决于处理程序的用例。

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

也可以点击下面的链接了解更多解释: 为什么是事件。目标不是元素在Typescript?

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

对于那些正在寻找一个解决方案来获得一个事件和存储一些东西,在我的情况下,一个HTML 5元素,在一个useState这里是我的解决方案:

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

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

结合Nitzan和Edwin的回答,我发现这样的东西对我很有用:

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