type react microsoft create cra app reactjs typescript types typescript-typings

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í