typescript输入 onchange event.target.value

IT技术 reactjs typescript types typescript-typings
2021-04-13 01:17:24

在我的react,typescript的应用程序,我使用:onChange={(e) => data.motto = (e.target as any).value}

我如何正确定义类的类型,这样我就不必用 hack 绕过类型系统any

export interface InputProps extends React.HTMLProps<Input> {
...

}

export class Input extends React.Component<InputProps, {}> {
}

如果我把target: { value: string };我得到:

ERROR in [default] /react-onsenui.d.ts:87:18
Interface 'InputProps' incorrectly extends interface 'HTMLProps<Input>'.
  Types of property 'target' are incompatible.
    Type '{ value: string; }' is not assignable to type 'string'.
6个回答

通常事件处理程序应该使用e.currentTarget.value,例如:

onChange = (e: React.FormEvent<HTMLInputElement>) => {
    const newValue = e.currentTarget.value;
}

您可以在此处阅读原因(Revert "Make SyntheticEvent.target generic, not SyntheticEvent.currentTarget.")。

UPD:正如@roger-gusmao 所提到的,ChangeEvent更适合输入表单事件。

onChange = (e: React.ChangeEvent<HTMLInputElement>)=> {
   const newValue = e.target.value;
}
哦对不起,你用过currentTarget在那种情况下,是的,它有效,但问题是关于target
2021-05-29 01:17:24
是的,你说得对,但正如github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 中提到的,target在大多数情况下使用不正确。此外,目标不必T强迫我们正确编写
2021-05-29 01:17:24
这根本行不通。value 不是接口 EventTarget 的属性
2021-06-04 01:17:24
当然不是 EventTarget,而是 HTMLInputElement 的一部分你可以在这里看到完整的定义github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/...
2021-06-09 01:17:24
这对我不起作用,我不得不将事件转换为React.ChangeEvent<HTMLInputElement>而不是 FormEvent。
2021-06-16 01:17:24

在 TypeScript 中使用的正确方法是

  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // No longer need to cast to any - hooray for react!
    this.setState({temperature: e.target.value});
  }

  render() {
        ...
        <input value={temperature} onChange={this.handleChange} />
        ...
    );
  }

跟着完整的课,比较好理解:

import * as React from "react";

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};


interface TemperatureState {
   temperature: string;
}

interface TemperatureProps {
   scale: string;

}

class TemperatureInput extends React.Component<TemperatureProps, TemperatureState> {
  constructor(props: TemperatureProps) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  //  handleChange(e: { target: { value: string; }; }) {
  //    this.setState({temperature: e.target.value});  
  //  }


  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // No longer need to cast to any - hooray for react!
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature} onChange={this.handleChange} />
      </fieldset>
    );
  }
}

export default TemperatureInput;
@JamesConkling 非常感谢!
2021-05-22 01:17:24
注意:为了确保类型可供选择,添加lib: ["dom"]compilerOptionstsconfig.json
2021-06-14 01:17:24
如果你有多个输入,你需要为每个输入一行吗?
2021-06-14 01:17:24
确保在 handleChange 函数中正确分配“this”的另一种方法是将 handleChange 编写为箭头函数,即 handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.setState(...); }; 通过这样做,人们将不再需要使用构造函数来绑定 handleEvent 函数。
2021-06-17 01:17:24
另一种处理“this”而不是使用构造函数和绑定方法的方法是使用 onChange 属性中的箭头函数,即 onChange={e => this.handleChange(e)}
2021-06-20 01:17:24

您可以执行以下操作:

import { ChangeEvent } from 'react';

const onChange = (e: ChangeEvent<HTMLInputElement>)=> {
   const newValue = e.target.value;
}

as HTMLInputElement 为我工作

那没有.target?
2021-05-27 01:17:24

target你试图在添加InputProps是不一样的target,你想这是在React.FormEvent

所以,我能想出的解决方案是,扩展事件相关类型以添加​​您的目标类型,如:

interface MyEventTarget extends EventTarget {
    value: string
}

interface MyFormEvent<T> extends React.FormEvent<T> {
    target: MyEventTarget
}

interface InputProps extends React.HTMLProps<Input> {
    onChange?: React.EventHandler<MyFormEvent<Input>>;
}

一旦你有了这些类,你就可以使用你的输入组件作为

<Input onChange={e => alert(e.target.value)} />

没有编译错误。事实上,您也可以将上面的前两个接口用于其他组件。

值类型不是字符串!
2021-06-20 01:17:24