reactjs - react - Entrada de mecanografía onchange event.target.value
typescript cra (6)
En mi aplicación de reacción y mecanografiado, uso:
onChange={(e) => data.motto = (e.target as any).value}
.
¿Cómo defino correctamente los tipings para la clase, para que no tenga que hackear el sistema de tipos con
any
?
export interface InputProps extends React.HTMLProps<Input> {
...
}
export class Input extends React.Component<InputProps, {}> {
}
Si pongo
target: { value: string };
Yo obtengo :
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''.
Aquí hay una manera con la desestructuración de objetos ES6, probada con TS 3.3.
Este ejemplo es para una entrada de texto.
name: string = '''';
private updateName({ target }: { target: HTMLInputElement }) {
this.name = target.value;
}
El
target
que intentó agregar en
InputProps
no es el mismo
target
que quería que está en
React.FormEvent
Entonces, la solución que se me ocurrió fue, extender los tipos relacionados con eventos para agregar su tipo de destino, como:
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>>;
}
Una vez que tenga esas clases, puede usar su componente de entrada como
<Input onChange={e => alert(e.target.value)} />
sin errores de compilación. De hecho, también puede usar las dos primeras interfaces anteriores para sus otros componentes.
En general, los controladores de eventos deben usar
e.currentTarget.value
, por ejemplo:
onChange = (e: React.FormEvent<HTMLInputElement>) => {
const newValue = e.currentTarget.value;
}
Puede leer por qué es así aquí https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239
UPD: Como mencionó @ roger-gusmao
ChangeEvent
más adecuado para escribir eventos de formulario.
onChange = (e: React.ChangeEvent<HTMLInputElement>)=> {
const newValue = e.target.value;
}
Por suerte, encuentro una solución. usted puede
importar {ChangeEvent} desde ''reaccionar'';
y luego escriba código como:
e:ChangeEvent<HTMLInputElement>
la forma correcta de usar en TypeScript es
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} />
...
);
}
Siga la clase completa, es mejor entender:
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;
as HTMLInputElement
funciona para mí