打字稿输入onchange event.target.value

Dan*_* K. 84 types typescript reactjs typescript-typings

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

我如何正确定义类的类型,所以我不必破解我的类型系统any

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

}

export class Input extends React.Component<InputProps, {}> {
}
Run Code Online (Sandbox Code Playgroud)

如果我把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'.
Run Code Online (Sandbox Code Playgroud)

Yoz*_*ozi 141

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

onChange = (e: React.FormEvent<HTMLInputElement>) => {
    const newValue = e.currentTarget.value;
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里阅读原因https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239

UPD:正如@ roger-gusmao所提到的ChangeEvent更适合打字表格事件.

onChange = (e: React.ChangeEvent<HTMLInputElement>)=> {
   const newValue = e.target.value;
}
Run Code Online (Sandbox Code Playgroud)

  • 这根本行不通.value不是EventTarget接口的属性 (8认同)
  • 这对我不起作用,我不得不将事件转换为 `React.ChangeEvent&lt;HTMLInputElement&gt;` 而不是 FormEvent。 (7认同)
  • 哦,抱歉,你使用了 `currentTarget`。在那种情况下,是的,它有效,但问题是关于“目标” (4认同)
  • 当然不是 EventTarget,而是 HTMLInputElement 的一部分你可以在这里看到完整的定义 https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L279 (2认同)
  • 是的,你说得对,但正如 https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 中提到的,在大多数情况下使用 `target` 是不正确的。而且,target 没有 `T` 来强制我们正确书写 (2认同)

Rog*_*mao 61

在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} />
        ...
    );
  }
Run Code Online (Sandbox Code Playgroud)

按照完整的课程,最好理解:

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;
Run Code Online (Sandbox Code Playgroud)

  • 注意:为确保类型可用,在`tsconfig.json`中的`compilerOptions`中添加`lib:[“ dom”]`。 (3认同)
  • 如果你有多个输入,你需要为每个输入一行吗? (2认同)

nav*_*gar 26

ChangeEvent<HTMLInputElement>是打字稿中更改事件的类型。它是这样完成的——

import { ChangeEvent } from 'react';

const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    setValue(event.target.value);
};
Run Code Online (Sandbox Code Playgroud)


小智 24

我们还可以使用定义类型(在功能组件中)的 onChange 事件触发,如下所示:

 const handleChange = (
    e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
  ) => {
        const name = e.target.name;
        const value = e.target.value;
};

Run Code Online (Sandbox Code Playgroud)


fjp*_*urr 10

尚未提及的另一种选择是键入 onChange 函数而不是它收到的 props。使用 React.ChangeEventHandler:

const stateChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
    console.log(event.target.value);
};
Run Code Online (Sandbox Code Playgroud)


hai*_*ind 8

as HTMLInputElement 适合我

  • 没有“.target”? (3认同)

Yil*_*maz 8

const handleChange = (
    e: ChangeEvent<HTMLInputElement>
  ) => {
    const { name, value } = e.target;
    this.setState({ ...currentState, [name]: value });
  };
Run Code Online (Sandbox Code Playgroud)

您可以将其应用于input表单组件中的每个元素


Leo*_*one 6

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>>;
}
Run Code Online (Sandbox Code Playgroud)

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

<Input onChange={e => alert(e.target.value)} />
Run Code Online (Sandbox Code Playgroud)

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


Bap*_*Bap 6

这是 ES6 对象解构的一种方法,已使用 TS 3.3 进行测试。
此示例适用于文本输入。

name: string = '';

private updateName({ target }: { target: HTMLInputElement }) {
    this.name = target.value;
}
Run Code Online (Sandbox Code Playgroud)


Blo*_*gic 6

使用子组件时,我们像这样检查类型。

父组件:

export default () => {

  const onChangeHandler = ((e: React.ChangeEvent<HTMLInputElement>): void => {
    console.log(e.currentTarget.value)
  }

  return (
    <div>
      <Input onChange={onChangeHandler} />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

子组件:

type Props = {
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
}

export Input:React.FC<Props> ({onChange}) => (
  <input type="tex" onChange={onChange} />
)
Run Code Online (Sandbox Code Playgroud)


小智 6

我使用这样的东西:

import { ChangeEvent, useState } from 'react';


export const InputChange = () => {
  const [state, setState] = useState({ value: '' });

  const handleChange = (event: ChangeEvent<{ value: string }>) => {
    setState({ value: event?.currentTarget?.value });
  }
  return (
    <div>
      <input onChange={handleChange} />
      <p>{state?.value}</p>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

  • 终于有东西起作用了。我仍然不明白为什么 ChangeEvent&lt;HTMLInputElement&gt; 在 currentTarger 或 target 上没有值... (4认同)

小智 5

幸运的是我找到了解决方案。您可以

从'react'导入{ChangeEvent};

然后编写如下代码: e:ChangeEvent<HTMLInputElement>


Dry*_*ams 5

这是当您使用对象时FileList

onChange={(event: React.ChangeEvent<HTMLInputElement>): void => {
  const fileListObj: FileList | null = event.target.files;
  if (Object.keys(fileListObj as Object).length > 3) {
    alert('Only three images pleaseeeee :)');
  } else {
    // Do something
  }

  return;
}}
Run Code Online (Sandbox Code Playgroud)


Meh*_*ari 5

这对我有用,而且它与框架无关。

const handler = (evt: Event) => {
  console.log((evt.target as HTMLInputElement).value))
}
Run Code Online (Sandbox Code Playgroud)