Referências do React fortemente tipadas com TypeScript
2 de Novembro de 2016 • 3 minutos para ler • typescript, reactQuem já trabalhou com React por algum tempo provavelmente já descobriu que refs
são bem fáceis de se trabalhar,
porém começam a se tornar inflexíveis a partir de certo ponto.
De qualquer forma, refs
estão disponíveis e funcionam muito bem. Então por que não utilizadas, correto?
Quando trabalhamos com TypeScript é uma pratica comum ter tudo o mais tipado possível.
Infelizmente refs
é tipado como [key: string]: ReactInstance
, o que nos forca a digitar this.refs["myInput]
. Definitivamente não é o que queremos.
Usando referências como callbacks
ref
como callback é a prática recomendada atualmente e a solução com TypeScript é bem simples.
import * as React from "react";
export class CustomTextInput extends React.Component<{}, {}> {
private textInput: HTMLInputElement;
constructor() {
super();
this.focus = this.focus.bind(this);
}
public focus() {
this.textInput.focus();
}
public render() {
return <div>
<input
type="text"
ref={(ref) => this.textInput = ref}
/>
<input
type="button"
value="Focus the text input"
onClick={this.focus}
/>
</div>;
}
}
export class AutoFocusTextInput extends React.Component<{}, {}> {
private input: CustomTextInput;
constructor() {
super();
}
protected componentDidMount() {
this.input.focus();
}
public render() {
return <div>
<CustomTextInput
ref={(ref) => this.input = ref}
/>
</div>;
}
}
Este exemplo é exatamente igual ao da documentação oficial.
A única pequena diferença é que adicionamentos uma propriedade tipada em nossa classe private textInput: HTMLInputElement;
.
Com isto agora é possível digitarmos this.input.value
, this.input.focus()
, this.input.maxLength
e assim por diante, sem erros de compilação.
Usando referências como string
Referências como string eventualmente serão depreciadas. Mas caso você ainda esteja utilizando e não quer migrar para callbacks, é também muito fácil adicionar tipagem à elas.
import * as React from "react";
export class CustomTextInput extends React.Component<{}, {}> {
public refs: {
textInput: HTMLInputElement;
};
constructor() {
super();
this.focus = this.focus.bind(this);
}
public focus() {
this.refs.textInput.focus();
}
public render() {
return <div>
<input
type="text"
ref="textInput"
/>
<input
type="button"
value="Focus the text input"
onClick={this.focus}
/>
</div>;
}
}
Estamos simplesmente sobrescrevendo a propriedade refs
para ser fortemente tipada. Sim, isto é tudo.
A única diferença entre este exemplo e o de cima é que neste estamos usando a propriedade padrão do React refs
, enquanto no outro estamos definindo uma nova.
Seja qual for sua preferência, apenas lembre-se de sempre “tipar” seus componentes React tanto quanto possível.