Você já se perguntou como surgiram os hooks do React e para que eles servem? Provavelmente, já utilizamos useState
e useEffect
, mas sabemos como surgiram, quais problemas resolvem e quais problemas podem causar se utilizados de forma inadequada em nossos projetos? Quando devemos usá-los e quando não devemos? Essas são perguntas que certamente já nos fizemos, e é para isso que estamos aqui.
Sejam muito bem-vindos a este curso de React, Hooks Essenciais, onde nos aprofundaremos teoricamente nos hooks essenciais do React, como useState
, useEffect
, useContext
, useReducer
, entre outros.
Audiodescrição: Neilton é um homem de pele negra, com olhos e cabelos escuros. No momento, está usando óculos com armação retangular e uma camisa amarela.
O que vamos aprender durante este curso? Este curso é um formato que estamos trazendo para que possamos nos aprofundar teoricamente.
Haverá uma série de vídeos em que cada um abordará um hook específico do React. Vamos entender como esse hook surgiu, sua anatomia, como utilizá-lo, para que serve, quando devemos usá-lo, e quais problemas ele pode resolver ou causar em nossa aplicação.
Após aprendermos sobre o hook, haverá atividades para testar nossos conhecimentos, incluindo atividades de múltipla escolha e uma atividade prática, onde aplicaremos o conhecimento adquirido em um projeto. Não se preocupe, pois disponibilizaremos um gabarito para orientação posterior.
Para participar deste curso, é necessário ter um conhecimento aprofundado de JavaScript e um conhecimento básico de React. É recomendado que já tenhamos criado algumas aplicações em React ao longo de nossa jornada. Isso é importante, pois o objetivo aqui é aprofundar nosso conhecimento nos hooks do React.
Estamos muito animados para começar e aprender mais sobre esses hooks incríveis que o React oferece. Nos vemos no próximo vídeo. Até lá!
Quando desenvolvemos aplicações em React, é comum utilizarmos alguns hooks, como useState
, useEffect
e até mesmo useContext
para recuperar o contexto de algo. No entanto, é importante entender como surgiram os hooks, quais problemas eles resolvem nas aplicações React e como utilizá-los da melhor forma possível.
Antes de tudo, precisamos compreender como era o React antes dos hooks. Antigamente, utilizávamos uma abordagem mais próxima do paradigma de orientação a objetos, com componentes React criados através de classes, os chamados class components. Nessa época, utilizávamos classes para criar componentes e gerenciar seus estados, o que trazia algumas complexidades para a aplicação. Por exemplo, o ciclo de vida era complicado, exigindo ações manuais quando o componente era montado ou atualizado, além de atualizações de estado. Isso tornava o código mais complexo e menos reutilizável.
Vamos observar um exemplo de componente React criado com classes. Temos um componente chamado Contador
, que é um class component estendendo React.Component
. Ele possui um construtor e métodos de classe, seguindo a abordagem do paradigma de programação orientada a objetos. Era necessário definir o estado e criar métodos para lidar com eventos, como a montagem ou atualização do componente. Se o estado fosse mais complexo, precisávamos criar outros métodos dentro do componente, tornando o código verboso e de difícil reutilização.
class Contador extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
componentDidMount() {
document.title = `Contagem: ${this.state.count}`;
}
componentDidUpdate() {
document.title = `Contagem: ${this.state.count}`;
}
render() {
return (
<div>
<p>Você clicou {this.state.count} vezes</p>
<button
onClick={() => this.setState({ count: this.state.count + 1 })}
>
Incrementar
</button>
</div>
);
}
}
A solução para essas dificuldades foi a criação dos hooks. Em 2019, com o lançamento da versão 16.8 do React, a equipe do React mudou de uma abordagem com Class Components para Functional Components. Essa mudança eliminou a necessidade de classes nos componentes, facilitando o uso de estados nas aplicações. Para pessoas desenvolvedoras experientes e iniciantes, essa abordagem funcional tornou o aprendizado do React mais fácil e amigável.
A principal novidade dessa mudança foi a introdução dos hooks. O mesmo componente de classe que vimos anteriormente, em uma versão com Functional Components e hooks, é definido como uma função. Utilizamos o hook useState
para lidar com o estado da aplicação, retornando algo semelhante ao JSX, que é parecido com HTML. O hook useState
retorna o estado e uma função para atualizá-lo, eliminando a necessidade de gerenciar manualmente o ciclo de vida do componente. Isso simplifica o código e facilita sua reutilização.
import { useState } from "react";
function Contador() {
const [count, setCount] = useState(0);
return (
<div>
<p>Você clicou {count} vezes</p>
<button onClick={() => setCount(count + 1)}>
Incrementar
</button>
</div>
);
}
Os hooks tornam o código mais simples e reutilizável, eliminando a necessidade de classes. Com Functional Components, podemos criar componentes como funções, o que é mais familiar para quem está começando com JavaScript e React. Além disso, os hooks facilitam o uso de estados. Com useState
, podemos criar quantos estados quisermos na aplicação, sem a necessidade de criar métodos para atualizá-los.
Vamos analisar a anatomia do hook useState
. Antes de entender seu funcionamento, é importante compreender o conceito de variáveis de estado no React. As variáveis de estado diferem das variáveis locais, pois, em re-renderizações, as variáveis locais são perdidas. O React cria novas referências para elas, e a informação anterior é perdida. Já as variáveis de estado permitem que o React lembre de dados entre re-renderizações.
Em uma entrevista de emprego, por exemplo, podemos explicar que variáveis de estado são dados que o React lembra entre re-renderizações. O hook useState
recebe um valor inicial como argumento, definindo o estado inicial da aplicação. Ele retorna um estado e uma função para atualizá-lo. O estado é uma variável de estado, que só pode ser atualizada com a função retornada pelo useState
, chamada setEstado
. Se tentarmos atualizar o estado de outra forma, o React não entenderá a alteração. É uma convenção declarar o nome da variável de estado, como estado
, e utilizar a função setEstado
para atualizá-la.
const [estado, setEstado] = useState(valorInicial);
Após definir uma função, utilizamos o prefixo set
antes do nome do estado. Por exemplo, se tivermos uma variável nome
, ela será nome
e setNome
, e para email
, será email
e setEmail
. Utilizamos a anotação de colchetes para desestruturação de array, que inclui o estado e a função que o altera. Esse é um conhecimento básico de JavaScript necessário para trabalhar com React. Aplicaremos e utilizaremos esses conhecimentos básicos de JavaScript com frequência.
Recapitulando, o estado representa o valor atual, enquanto setEstado
é a função usada para alterar esse valor. O valor inicial define o estado inicial. No useState
, podemos utilizar tipos como booleanos, strings, números, arrays ou objetos. É importante ter cuidado ao atualizar tipos de dados, especialmente arrays e objetos.
Vamos demonstrar isso com código. Estamos utilizando a plataforma IDX, desenvolvida pelo Google, que permite criar aplicações front-end, back-end e mobile online, sem necessidade de configuração local. Nosso objetivo é analisar exemplos de hooks que estamos estudando teoricamente.
No código do componente, utilizamos useState
com count
e setCount
, passando o valor inicial 0. Criamos uma função handleClick
, que chama setCount
três vezes. Ao clicar no botão, a função handleClick
é chamada, incrementando o contador. No entanto, ao clicar, o contador incrementa de 1 em 1, não de 3 em 3, como esperado.
import { useState } from 'react'
function Contador() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
}
return (
<>
<h1>useState()</h1>
<div className="card">
<button onClick={handleClick}>
count is {count}
</button>
</div>
</>
)
}
export default Contador
Isso ocorre porque o React chama a função de atualização de estado apenas uma vez por execução. Para chamar a função mais de uma vez, utilizamos o conceito de estado anterior, ou prevState
. Na função handleClick
, passamos uma função de callback para setCount
, utilizando prevCount
para atualizar o estado com base no estado anterior.
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
Ao recarregar a aplicação e clicar no botão, setCount
é chamado três vezes corretamente. Isso acontece porque, ao basear-se no estado anterior, colocamos a execução em uma fila, considerando o estado anterior na próxima atualização. Assim, ao chamar handleClick
, conseguimos executar setState
mais de uma vez.
Outro detalhe importante é quando temos objetos como estado. Objetos podem ser mutados durante a execução do código. Em vez de acessar diretamente as propriedades do objeto, criamos um novo objeto utilizando o spread operator para manter o estado consistente. Isso é válido tanto para objetos quanto para matrizes.
const [form, setForm] = useState({firstName: 'Andy', lastName:'Jones'});
// Ao invés disso:
form.firstName = "Taylor";
// Prefira isso:
setForm({
...form,
firstName: "Taylor",
});
Se houver dúvidas, podemos utilizar o fórum para esclarecimentos. Deixaremos algumas atividades para praticar o uso do useState
, incluindo casos reais apresentados. Nos vemos em breve.
Já devemos ter utilizado alguns hooks do React ao desenvolver nossas aplicações, como useState
, useEffect
e até mesmo useContext
para recuperar o contexto de algo. No entanto, sabemos como surgiram os hooks e quais problemas eles resolvem em nossas aplicações React? E mais, sabemos realmente utilizar esses hooks da melhor forma possível? É isso que vamos descobrir.
Antes de tudo, precisamos entender como era o React sem os hooks. Antigamente, utilizávamos uma abordagem mais próxima do paradigma de orientação a objetos. Os componentes React eram criados com classes, os chamados class components. Utilizávamos a classe para criar os componentes e também para gerenciar os estados dos mesmos, o que trazia algumas complexidades para nossa aplicação. Por exemplo, o ciclo de vida era complicado, exigindo que disparássemos ações manualmente quando o componente era montado ou atualizado, além de atualizar o estado de uma certa forma. Isso tornava o código complexo e pouco reutilizável.
Vamos observar um componente React criado com classes. Temos um componente chamado de contador, que é um class component. Ele estende algo do React, como React.component
, e possui um constructor e métodos da classe, seguindo a abordagem do paradigma de programação orientada a objetos. Precisávamos definir o estado e criar métodos para lidar com eventos, como quando o componente era montado ou atualizado. Se tivéssemos um estado mais complexo, era necessário criar outros métodos dentro do componente para atualizá-lo, o que deixava o código verboso. A reutilização também era difícil, pois precisávamos realizar ações específicas quando o componente era montado ou atualizado. O gerenciamento de estados era complexo, exigindo a criação de métodos adicionais para lógica de atualização de estados.
A solução para isso foi a criação dos hooks. A partir de 2019, com o lançamento da versão 16.8 do React, a equipe do React mudou de uma abordagem com Class Components para uma abordagem com Functional Components, que são componentes funcionais definidos por meio de funções. Isso eliminou a necessidade de classes nos componentes, simplificando o uso de estados nas aplicações. Para pessoas desenvolvedoras experientes e iniciantes, essa mudança foi benéfica, tornando o aprendizado do React mais fácil e amigável.
A principal novidade dessa mudança para componentes funcionais foi a introdução dos hooks. O mesmo componente de classe que vimos anteriormente, em uma versão com Functional Components e hooks, tinha uma estrutura diferente. Definíamos o componente contador e utilizávamos um hook do React chamado useState
para lidar com o estado da aplicação. Retornávamos algo semelhante ao JSX da aplicação, que se assemelha ao HTML, e o hook useState
retornava o estado e uma função para atualizá-lo. Não precisávamos nos preocupar com ações específicas quando o componente era montado, pois tudo era gerenciado pelo React através dos hooks. Isso eliminou a complexidade do código e a necessidade de lidar manualmente com esses aspectos.
Recapitulando, os hooks tornam o código mais simples e reutilizável. O componente de contador, por exemplo, reduziu bastante de tamanho. Eles eliminam a necessidade de classes, permitindo que criemos componentes como funções, o que é mais amigável para quem está migrando do JavaScript para o React. Além disso, facilitam o uso de estados. Com o useState
, podemos criar quantos estados quisermos na aplicação, sem a necessidade de criar métodos para atualizá-los.
Vamos analisar a anatomia do hook useState
. Antes de entender como ele funciona, precisamos compreender um conceito importante do React: as variáveis de estado. Elas se diferenciam de variáveis locais, pois, quando definimos uma variável local no React, ela é perdida a cada re-renderização. O React cria novas variáveis locais e referências, perdendo a informação anterior. Com as variáveis de estado, o React lembra dos dados entre re-renderizações. Se formos questionados em uma entrevista de emprego sobre a diferença entre variáveis de estado e variáveis locais, podemos explicar que as variáveis de estado são dados que o React lembra entre re-renderizações.
Voltando à anatomia do hook, o useState
recebe como parâmetro um valor inicial, que define o estado inicial da aplicação. Ele retorna um estado e uma função para atualizá-lo. O estado é uma variável de estado e só pode ser atualizado com a função retornada pelo useState
, que é o setEstado
. Se tentarmos atualizar um estado do React de outra forma, o React não entenderá a alteração. Portanto, é necessário utilizar o setState
.
Existe uma convenção para declararmos o nome da variável de estado. No caso, estamos definindo como estado
, e a função é definida com o prefixo set
antes do nome do estado. Por exemplo, se fosse uma variável nome
, seria nome
e setNome
; para email
, seria email
e setEmail
. Utilizamos a anotação de colchetes, que contém o estado e a função que altera ou atualiza o estado, representando a desestruturação de array. Esse é um conhecimento básico de JavaScript que precisamos ter ao trabalhar com React, pois aplicaremos esses conceitos com frequência.
Recapitulando, o estado
representa o valor atual, enquanto setEstado
é a função usada para alterar esse valor. Também definimos um valor inicial para o estado. No useState
, o estado pode ser um booleano, uma string, um número, um array ou objetos. Podemos definir o estado inicial com esses tipos primitivos, mas devemos ter cuidado ao atualizar alguns tipos de dados, especialmente arrays e objetos.
Vamos exemplificar com código. Estamos utilizando a plataforma IDX, desenvolvida pelo Google, onde é possível criar aplicações front-end, back-end e mobile. A IDX funciona como uma IDE no navegador, permitindo que trabalhemos online sem precisar configurar ou baixar programas. Nosso objetivo é analisar exemplos de hooks que estamos estudando teoricamente.
Temos um código de componente React utilizando useState
com count
, setCount
e o valor inicial 0. Criamos uma função handleClick
que chama setCount
três vezes. Retornamos um título e um botão que, ao ser clicado, chama handleClick
e incrementa o contador. A aplicação está rodando na janela "web" do IDX. Ao clicar no contador, ele incrementa de 1 em 1, mesmo que handleClick
chame setCount
três vezes. Isso ocorre porque o React chama a função de atualização de estado apenas uma vez por execução.
Se precisarmos chamar uma função que atualiza o estado mais de uma vez, utilizamos o conceito de estado anterior, ou prevState
. Dentro de handleClick
, passamos uma função de callback para cada setCount
, utilizando prevCount
para atualizar o estado com base no estado anterior. Isso coloca a execução em uma fila, considerando o estado anterior na próxima atualização.
Ao chamar handleClick
, o count
é atualizado através de prevCount
. Inicialmente, é zero, somando um, fica um. Na segunda execução, soma-se mais um, resultando em dois, e na terceira, soma-se mais um, resultando em três. Assim, conseguimos executar setState
mais de uma vez. É importante entender que, para chamar setCount
mais de uma vez em uma única execução, devemos nos basear no estado anterior, utilizando a convenção prevCount
para clareza e legibilidade.
Outro detalhe importante ao atualizar estados é quando lidamos com objetos e arrays. Objetos podem ser mutados durante a execução do código. Ao invés de acessar diretamente as propriedades do objeto, como form.firstName
, e mutar o estado, devemos criar um novo objeto. Utilizamos o Spread Operator para copiar o conteúdo do objeto anterior e atualizamos apenas a parte desejada, como firstName
. Essa abordagem é mais segura, garantindo um estado consistente.
Discutimos bastante sobre useState
. Caso haja dúvidas, podem ser colocadas no fórum, onde estaremos disponíveis para ajudar. Deixaremos algumas atividades para praticar o uso do useState
, incluindo casos reais apresentados durante a aula. Nos vemos em breve.
O curso React: explore e aprofunde seus conhecimentos nos hooks essenciais possui 129 minutos de vídeos, em um total de 45 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.