Qual é o tipo correcto para Reagir a eventos. Inicialmente só utilizei "qualquer" por uma questão de simplicidade. Agora, estou a tentar limpar as coisas e evitar a utilização de "qualquer" completamente.
Assim, de uma forma simples como esta:
export interface LoginProps {
login: {
[k: string]: string | Function
uname: string
passw: string
logIn: Function
}
}
@inject('login') @observer
export class Login extends Component<LoginProps, {}> {
update = (e: React.SyntheticEvent<EventTarget>): void => {
this.props.login[e.target.name] = e.target.value
}
submit = (e: any): void => {
this.props.login.logIn()
e.preventDefault()
}
render() {
const { uname, passw } = this.props.login
return (
<div id='login' >
<form>
<input
placeholder='Username'
type="text"
name='uname'
value={uname}
onChange={this.update}
/>
<input
placeholder='Password'
type="password"
name='passw'
value={passw}
onChange={this.update}
/>
<button type="submit" onClick={this.submit} >
Submit
</button>
</form>
</div>
)
}
}
Que tipo de evento uso aqui como tipo de evento?
React.SyntheticEventnão parece estar a funcionar pois recebo um erro que
nomee
valornão existem no
alvo`.
Uma resposta mais generalizada para todos os eventos seria realmente apreciada.
Obrigado
A interface SyntheticEvent é genérica:
interface SyntheticEvent<T> {
...
currentTarget: EventTarget & T;
...
}
E o currentTarget
é uma intersecção da restrição genérica e do EventTarget
.
Além disso, uma vez que os seus eventos são causados por um elemento de entrada, deve utilizar o FormEvent
(em ficheiro de definição, os documentos de reacção).
Deve ser:
update = (e: React.FormEvent<HTMLInputElement>): void => {
this.props.login[e.currentTarget.name] = e.currentTarget.value
}
O problema não é com o tipo de Evento, mas que a interface EventTarget em datilografia tem apenas 3 métodos:
interface EventTarget {
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
dispatchEvent(evt: Event): boolean;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
interface SyntheticEvent {
bubbles: boolean;
cancelable: boolean;
currentTarget: EventTarget;
defaultPrevented: boolean;
eventPhase: number;
isTrusted: boolean;
nativeEvent: Event;
preventDefault(): void;
stopPropagation(): void;
target: EventTarget;
timeStamp: Date;
type: string;
}
Portanto, é correcto que "nome" e "valor" don'não existam no EventTarget. O que precisa de fazer é lançar o alvo para o tipo de elemento específico com as propriedades de que necessita. Neste caso, será HTMLInputElement
.
update = (e: React.SyntheticEvent): void => {
let target = e.target as HTMLInputElement;
this.props.login[target.name] = target.value;
}
Também para eventos em vez de React.SyntheticEvent, pode também escrevê-los como se segue: "Event", "MouseEvent", "KeyboardEvent"...etc., depende do caso de utilização do manipulador.
A melhor maneira de ver todas estas definições de tipo é verificar os ficheiros .d.ts de ambos os tipos de datilografia & reagir.
Verifique também o seguinte link para mais explicações: https://stackoverflow.com/questions/28900077/why-is-event-target-not-element-in-typescript
Para combinar as respostas de Nitzan's e Edwin's, descobri que algo como isto funciona para mim:
update = (e: React.FormEvent<EventTarget>): void => {
let target = e.target as HTMLInputElement;
this.props.login[target.name] = target.value;
}