O React Hooks é a nova API adicionada ao React 16.8. Eles nos permitem utilizar o state e alguns recursos de lifecycle sem a necessidade de usar classes. Essa possibilidade de utilizar outras ferramentas, facilita bastante os componentes que utilizam função e não uma classe em si, que encurta a sintaxe e, consequentemente, melhora a performance.

Por ANDERSON HENRIQUE DE SÁ SILVA
O que acontecerá com as classes?
As classes ainda vão continuar existindo e não há pretensão nenhuma de removê-las segundo a documentação do React. Essa API não irá substituir seus conhecimentos de React, mas também possui total compatibilidade com os códigos mais antigos.
Qual a utilidade do hooks?
A vantagem é você escrever menos códigos de uma forma mais simples e funcional, sem precisar de uma classe para isso e diversos tipos de lifecycle, o que também facilita a legibilidade do código por ser funções mais simples e diretas. Além disso, também há maior controle sobre os efeitos colaterais, não necessitando mais verificar os valores anteriores com os atuais no componentDidUpdate, como era preciso em algumas ocasiões. Você pode saber mais sobre os benefícios do Hooks aqui.
O que fazer para aplicar o hooks?
Como mencionado anteriormente, você precisa ter o React 16.8 e apenas isto já é o suficiente para testar essa nova funcionalidade. Então vamos colocar a mão na massa?
Primeiramente, vamos criar a aplicação react com o
“create-react-app” . Se você não possui, é possível instalá-lo utilizando o comando “npm i -g create-react-app” ou simplesmente usar o npx como demostrado aqui. E
xecute o seguinte comando:create-react-app react-hooks
Aguarde o término da instalação, depois de finalizado, podemos deletar alguns arquivos para ficar mais limpo e começarmos. Delete os arquivos (“index.css”, “logo.svg”, “serviceWorkers.js”, “App.test.js”) que estão na pasta "src" e crie um arquivo “Content.jsx”.
Ficando assim:

Abra o arquivo index.js, remova tudo o que está abaixo da linha 8 e as importações do “index.css” e do “serviceWorkers”, como mostra a imagem a seguir:

Agora vamos para o arquivo App.js, A partir desse ponto começa a ficar interessante: na linha da importação do React vamos adicionar também as funções useState e useEffect que provém dos hooks e que serão explicadas adiante. Também é necessário importar o nosso arquivo Content.jsx que criamos, ficando assim:

Vamos a explicação do useState e useEffect
useState
Essa função basicamente retorna um array, como pode ser visto na implementação da mesma.
Esse array retornado, traz um estado que será setado e uma função que mudará esse estado. Ficou confuso? Vamos ver na prática.

Veja que do retorno dela, eu criei uma variável que chama repositoryData: ela será o estado e outra, que se chama setRepositoryData, será a função que irá alterar o estado (repositoryData). A função useState também recebe um parâmetro que será o valor inicial do estado. Como eu passei null, o estado inicial é nulo. Em termos de React utilizando classe seria equivalente a isso:
this.state = {
repositoryData: null
}
A utilidade da função useState é exatamente essa e, como no React com classe, quando o estado é alterado, a página é renderizada.
Você pode consultar mais sobre o useState aqui.
useEffect
Essa função basicamente trata efeitos colaterais que serão os nossos “lifecycle”, se podemos por assim dizer. Ela pode ser equivalente a componentDidMount, componentDidUpdate e componentWillUnmount.
A cara dela é a seguinte:

Essa função da imagem seria equivalente a componentDidMount, repare que tem um array vazio após a vírgula, isso quer dizer que ela só executará uma vez. Você pode passar uma variável também dentro do array, fazendo isso, toda vez que a variável for alterada, essa função será chamada novamente. Mais detalhes nesse link.
Explicado isso, vamos a nossa implementação. Dentro do App.js adicione as seguintes linhas de código:
import React, { useEffect, useState } from 'react';
import Content from './Content'
import './App.css';
function App() {
const [ repositoryData, setRepositoryData ] = useState(null)
useEffect(() => {
fetch('https://api.github.com/users/AndersonHqds/repos')
.then(res => res.json())
.then(addLikeToObject)
.then(setRepositoryData)
}, [])
const likeAction = (id) =>{
const newRepositoryData = repositoryData.map(data => {
if(data.id == id) data.isLiked = !data.isLiked
return data
})
setRepositoryData(newRepositoryData)
}
const addLikeToObject = (obj) => {
const newRepoData = obj.map(data => ({ ...data, isLiked: false }) )
return newRepoData
}
return (
<div className="App">
<header>
<span>React Hooks</span>
</header>
<div className="content">
{
repositoryData ?
repositoryData.map(
data => <Content id={data.id}
key={data.id}
id={ data.id }
name={ data.name }
html_url={ data.html_url }
isLiked={ data.isLiked }
likeAction={ (id) => likeAction(id) }/>
)
: <div>Loading ....</div>
}
</div>
</div>
);
}
export default App;
Vamos às explicações: nossa função useEffect que está fazendo o papel do componentDidMount irá consultar a API do github através do método fetch, quando retornado os dados, eles serão convertidos para json e em seguida passado para a função
addLikeToObject.

Essa função basicamente vai modificar o objeto retornado, adicionando um valor “isLiked” para os objetos e setando como false, depois retorna esse novo objeto. Retornamos a função useEffect que irá pegar o valor retornado de addLikeToObject e irá passar para setRepositoryData. Se lembra? A função que altera nosso estado repositoryData.

Quando setRepositoryData receber os dados, ela irá armazená-los na variável repositoryData que será nosso estado. Logo depois, no retorno do nosso componente, verificamos se esse estado é nulo (estado inicial) ou se foi setado (
os novos dados).Caso for nulo, mostra uma mensagem de carregando, caso já tenha sido setado, mostra o componente contido passando as props para ele.

Nada complicado né? A nossa função likeAction basicamente se encarregará de mudar o valor de isLiked do nosso objeto, através do id e chamará nossa função setRepositoryData para que nosso estado seja alterado e a página renderizada novamente, quando a propriedade isLiked for modificada.
Recapitulando, a lógica é basicamente a seguinte:
1 - A requisição é feita para a API do github, através fetch dentro do
useEffect2 - É adicionado a chave isLiked para o objeto retornado
3 - O estado inicia como nulo, a condição dentro do return verá que é nulo e mostrará a mensagem “Loading….”
4 - O estado é setado no último then do fetch através da função
setRepositoryData5 - A renderização acontece e dessa vez o estado não é nulo, então nosso componente Content é renderizado passando (id, name, html_url, isLiked, likeAction) como propriedade.
Obs: Atenção na props likeAction pois ela é um callback que será chamado pelo componente filho.
Vamos ao nosso componente Content agora, abra o arquivo Content.jsx e adicione o seguinte código:
====================
import React from 'react';
const Content = (props) =>{
return(
<div className="card">
<div className="repository-header">
<span><b>GITHUB</b></span>
</div>
<div className="repository-content">
<div>
<span>Name: { props.name }</span>
</div>
<div>
<span>Url: <a href={ props.html_url }>{ props.html_url }</a></span>
</div>
<button className="like-button" onClick={(e) => props.likeAction(props.id) }>
{ !props.isLiked ? "Like" : "Unlike" } </button>
</div>
</div>
)
}
export default Content
=========================
Basicamente, aqui não tem segredo, recebemos as props passadas pelo componente pai e mostramos. Atenção somente a tag <button> pois ela será responsável por passar o id para a nossa função likeAction do componente App, também faz uma verificação se estiver isLiked estiver marcado como true, será mostrado o texto Unlike e caso o contrario será mostrado o texto
Like.Nossa funcionalidade já está feita, vamos só adicionar o css agora. A estilização sai do escopo do artigo, então é só copiar o código e colar dentro de App.css, segue o código:
body, * { margin: 0; padding: 0; }
header{ width: 100%; height: 80px; background-color: #383a3d; display: flex; align-items: center;}
header span { margin-left: 20px; font-weight: bold; font-size: 1.5em; color: #FFF;}
.content{ width: 100%; display: flex; flex-direction: column; align-items: center;}
.repository-header {height: 50px; background-color: #000; text-align: center; }
.repository-header span{ color: #FFF; font-size: 30px;}
.card { width: 400px; height: auto; margin: 10px 0; box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); transition: 0.3s; }
.repository-content { padding: 10px}
.repository-content span {font-size: 1.2em;}
.like-button { padding: 5px; cursor: pointer; margin-top: 20px;}
Com isso é para que o seguinte resultado seja obtido:

Espero ter deixado claro algumas coisas sobre o React Hooks, ele tem outras funcionalidades mas o artigo iria acabar ficando muito grande. No próximo artigo eu irei mostrar como utilizar o Redux através de Hooks. Qualquer dúvidas ou sugestões é só comentar obrigado.
Para mais detalhes sobre outros hooks, você pode estar consultado nesse link.