Embora eu adore o ReactJS, posso dizer que às vezes acho que as interações que eram fáceis durante o pré-ReactJS são irritantemente difíceis ou, no mínimo, “indiretas”. Um exemplo é garantir adequadamente que um determinado <input> seja focalizado quando um botão em um componente diferente é clicado; antigamente, eram três linhas de código, mas com o React pode ser mais.
Vamos dar uma olhada em algumas estratégias para focar adequadamente no <input> com o ReactJS.
autofocus
O autofocus é honrado no ReactJS, mas somente quando o atributo <input> é renderizado novamente com o React:
<input type="text" autofocus="true" />
autofocus é fácil de usar, mas só funciona quando o <input> é renderizado inicialmente; como o React, de forma inteligente, só renderiza novamente os elementos que foram alterados, o autofocus não é confiável em todos os casos.
componentDidUpdate com ref
Como não podemos nos basear apenas no autofocus podemos usar o atributo componentDidUpdate para completar o foco:
class Expressions extends Component {
_input: ?HTMLInputElement;
// ....
componentDidUpdate(prevProps, prevState) {
this._input.focus();
}
render() {
return (
<div className={this.state.focused ? "focused": ""}>
<input
autofocus="true"
ref={c => (this._input = c)}
/>
</div>
);
}
}
}
componentDidUpdate é acionado depois que o componente é atualizado, portanto, qualquer alteração no componente pai acionaria esse método e o seu <input> receberia o foco. Nos meus casos, geralmente altero um className no elemento pai para sinalizar que o elemento está ativo e, portanto, o componentDidUpdate será acionado.
Minha perspectiva da interação entre widgets foi formada pelos dias da estrutura dijit UI do Dojo, em que cada widget geralmente tinha uma referência a cada widget filho; com o ReactJS, essa prática está (espero) sendo evitada. refs e usar stateo que é lógico, mas ainda há uma parte de mim que anseia por uma referência simples, e é por isso que a segunda estratégia faz sentido para mim.