Typescript input onchange event.target.value
В моем приложении реакции и 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, {}> {
}
Если я поставлю 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'.
Ответы
Ответ 1
Обычно обработчики событий должны использовать e.currentTarget.value
, например:
onChange = (e: React.FormEvent<HTMLInputElement>) => {
const newValue = e.currentTarget.value;
}
Вы можете прочитать, почему это так, здесь (Отменить "Сделайте SyntheticEvent.target универсальным, а не SyntheticEvent.currentTarget.").
UPD: Как уже упоминалось @roger-gusmao ChangeEvent
, больше подходит для ввода событий формы.
onChange = (e: React.ChangeEvent<HTMLInputElement>)=> {
const newValue = e.target.value;
}
Ответ 2
правильный способ использования в 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;
Ответ 3
as HTMLInputElement
работает для меня
Ответ 4
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)} />
без ошибок компиляции. Фактически вы также можете использовать первые два интерфейса выше для ваших других компонентов.
Ответ 5
Мне повезло, я нашел решение.
вы можете
import {ChangeEvent} из 'response';
а затем напишите код:
e:ChangeEvent<HTMLInputElement>
Ответ 6
Вот способ разрушения объекта ES6, протестированный на TS 3.3.
Этот пример для ввода текста.
name: string = '';
private updateName({ target }: { target: HTMLInputElement }) {
this.name = target.value;
}
Ответ 7
Это когда вы работаете с объектом 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;
}}
Ответ 8
function handle_change(
evt: React.ChangeEvent<HTMLInputElement>
): string {
evt.persist(); // This is needed so you can actually get the currentTarget
const inputValue = evt.currentTarget.value;
return inputValue
}
И убедитесь, что в вашем tsconfig
есть "lib": ["dom"]
.
Ответ 9
Вы можете определить тип "any" для e.
onChange = {(e: any) = > data.motto = e.target.value}