React Hooks
Neste artigo pretendo demonstrar a nova funcionalidade do React chamada Hooks.
- Introdução
- Cenário atual
- O que são React Hooks?
- Vantagens
- Hook useState
- Reutilizando os Hooks
- Próximos passos
- Conclusão
Introdução
Entre os dias 25 e 26 de outubro de 2018, aconteceu a ReactConf 2018 em Las Vegas. O evento foi transmitido através do YouTube e eu pude acompanhar a apresentação do Dan Abramov sobre React Hooks. Durante e após a apresentação, o assunto React Hooks caiu nas graças da comunidade.
Cenário atual
Sempre que precisamos controlar o estado de um input
, precisamos criar uma classe, inicializar o estado do componente (o estado precisa ser um objeto), criar o método para tratar as alterações do estado do componente e fazer o bind
desse método para que ele tenha acesso ao objeto this
.
Para demonstrar um cenário muito comum, vou criar um componente semelhante à um formulário de contato. Nesse primeiro exemplo, vou adicionar apenas 01 input
ao formulário.
// importar o React e o Component para criar a classeimport React, { Component } from 'react';// exportar uma classe chamada ContactFormexport default class ContactForm extends Component {constructor(props) {// inicializar o contrutorsuper(props);// inicializar o estado do componentethis.state = { name: 'Roberto Achar' };// fazer o `bind` do método para que ele tenha acesso ao objeto `this`this.handleName = this.handleName.bind(this);}// criar o método para tratar as alterações do input namehandleName(e) {this.setState({ name: e.target.value });}// renderizar o componenterender() {return (<div><input type="text" value={this.state.name} onChange={this.handleName} /></div>);}}
Para adicionar mais campos a esse formulário, é necessário adicionar os novos campos ao objeto state
, criar métodos para tratar as alterações dos novos campos e fazer o bind
desses métodos para que eles tenham acesso ao objeto this
.
// importar o React e o Component para criar a classeimport React, { Component } from 'react';// exportar uma classe chamada ContactFormexport default class ContactForm extends Component {constructor(props) {// inicializar o contrutorsuper(props);// inicializar o estado do componentethis.state = {name: 'Roberto Achar',message: 'Mensagem...'};// fazer o `bind` dos métodos para que eles tenham acesso ao objeto `this`this.handleName = this.handleName.bind(this);this.handleEmail = this.handleEmail.bind(this);this.handleMessage = this.handleMessage.bind(this);}// criar o método para tratar as alterações do input namehandleName(e) {this.setState({ name: e.target.value });}// criar o método para tratar as alterações do input emailhandleEmail(e) {this.setState({ email: e.target.value });}// criar o método para tratar as alterações do input messagehandleMessage(e) {this.setState({ message: e.target.value });}// renderizar o componenterender() {return (<div><input type="text" value={this.state.name} onChange={this.handleName} /><inputtype="text"value={this.state.email}onChange={this.handleEmail}/><textarearows="3"value={this.state.message}onChange={this.handleMessage}/></div>);}}
Podemos simplificar e fazer as alterações do estado do componente de forma
inline
ou construir um único método que faça as alterações de forma dinâmica. 😉
O que são React Hooks?
É um conjunto de novas funcionalidades que permitem que você controle o estado da aplicação, além de outras funcionalidades, sem a necessidade da utilização de classes.
Essas novas funcionalidades não alteram em nada a forma como nossas aplicações são construídas e a utilização de classes continuará sendo permitida. React Hooks vem para melhorar a forma como construímos nossas aplicações, mas de maneira opcional.
É extremamente importante comentar que embora tenha sido apresentado na ReactConf, React Hooks ainda é uma proposta (proposal), ou seja, está em fase experimental, aguardando novos comentários da comunidade e ainda não está pronto para ser utilizado em produção. Os Hooks estão disponíveis na versão 16.7.0-alpha.0 para quem quiser brincar.
$ npm i react@next react-dom@next
Para mais informações sobre React Hooks, acesse: https://reactjs.org/hooks.
Vantagens
As vantagens de utilizar React Hooks são:
- Não será mais necessário a utilização de classes
- Evitará a utilização de
this
ebind()
, conceitos que geram muita confusão principalmente para iniciantes - Poderemos dividir e separar componentes funcionais e torná-los reutilizáveis
- Os testes serão muito mais fáceis, justamente por causa da separação de componentes
Hook useState
Com o React Hooks, poderemos construir a mesma funcionalidade sem a necessidade de utilizar classes. Utilizando o Hook useState
, poderemos adicionar a funcionalidade state
do React para componentes que retornam apenas uma função (function components
).
// importar o React e o useStateimport React, { useState } from 'react';// definir o nosso componente sem a necessidade de utilizar classeconst ContactForm = () => {// inicializar o estado do componenteconst [name, setName] = useState('Roberto Achar');// renderizar o componentereturn (<div><inputtype="text"value={name}onChange={(e) => setName(e.target.value)}/></div>);};// exportar o componenteexport default ContactForm;
Para adicionar mais campos à esse formulário, é necessário apenas inicializar os novos campos com useState
.
// importar o React e o useStateimport React, { useState } from 'react';// definir o nosso componente sem a necessidade de utilizar classeconst ContactForm = () => {// inicializar o estado do componenteconst [name, setName] = useState('Roberto Achar');const [message, setMessage] = useState('Mensagem...');// renderizar o componentereturn (<div><inputtype="text"value={name}onChange={(e) => setName(e.target.value)}/><inputtype="text"value={email}onChange={(e) => setEmail(e.target.value)}/><textarearows="3"value={message}onChange={(e) => setMessage(e.target.value)}/></div>);};// exportar o componenteexport default ContactForm;
Reutilizando os Hooks
Um dos maiores benefícios dos Hooks é a reutilização de funcionalidades. No exemplo anterior, estamos utilizando 03 vezes o Hook useState
para tratar as alterações de name
, email
e message
.
Podemos construir uma funcionalidade separada para tratar os 03 campos com mais facilidade e reutilizar essa funcionalidade no formulário.
// importar o Hook useStateimport { useState } from 'react';// criar a funcionalidade `useInput` e aceitar o valor inicial como parâmetroconst useInput = (initial) => {// inicializar o estadoconst [value, setValue] = useState(initial);// exportar um objeto com o `value` e o método `onChange`// o método `onChange` já trata a mudança de estadoreturn {value,onChange: (e) => setValue(e.target.value)};};// exportar a nova funcionalidadeexport default useInput;
Podemos reutilizar a funcionalidade useInput
para tratar o estado dos 03 campos de uma maneira mais "elegante".
// importar o Reactimport React from 'react';// importar a funcionalidade `useInput` que criamos anteriormenteimport useInput from './useInput';// definir o nosso componente sem a necessidade de utilizar classeconst ContactForm = () => {// inicializar o estado do componente através do `useInput`const name = useInput('Roberto Achar');const message = useInput('Mensagem vai aqui...');// renderizar o componente// utilizar `destructuring` para adicionar `value` e `onChange` no `input`return (<div><input type="text" {...name} /><input type="text" {...email} /><textarea rows="3" {...message} /></div>);};// exportar o componenteexport default ContactForm;
Próximos passos
Assistir a apresentação do Dan Abramov sobre React Hooks na ReactConf 2018
Ler mais a respeito na documentação disponível no site do React
Acompanhar a "awesome list" do React Hooks
Conclusão
Esse é apenas o começo do React Hooks. A aprensentaçao do Dan Abramov foi um pouco além e quero atualizar esse artigo com mais informações sobre Hooks.