The Codest
  • Sobre nós
  • Serviços
    • Desenvolvimento de software
      • Desenvolvimento de front-end
      • Desenvolvimento backend
    • Staff Augmentation
      • Programadores Frontend
      • Programadores de back-end
      • Engenheiros de dados
      • Engenheiros de nuvem
      • Engenheiros de GQ
      • Outros
    • Aconselhamento
      • Auditoria e consultoria
  • Indústrias
    • Fintech e Banca
    • E-commerce
    • Adtech
    • Tecnologia da saúde
    • Fabrico
    • Logística
    • Automóvel
    • IOT
  • Valor para
    • CEO
    • CTO
    • Gestor de entregas
  • A nossa equipa
  • Case Studies
  • Saber como
    • Blogue
    • Encontros
    • Webinars
    • Recursos
Carreiras Entrar em contacto
  • Sobre nós
  • Serviços
    • Desenvolvimento de software
      • Desenvolvimento de front-end
      • Desenvolvimento backend
    • Staff Augmentation
      • Programadores Frontend
      • Programadores de back-end
      • Engenheiros de dados
      • Engenheiros de nuvem
      • Engenheiros de GQ
      • Outros
    • Aconselhamento
      • Auditoria e consultoria
  • Valor para
    • CEO
    • CTO
    • Gestor de entregas
  • A nossa equipa
  • Case Studies
  • Saber como
    • Blogue
    • Encontros
    • Webinars
    • Recursos
Carreiras Entrar em contacto
Seta para trás VOLTAR
2021-12-07
Desenvolvimento de software

Um olhar mais profundo sobre os ganchos React mais populares

The Codest

Pawel Rybczynski

Software Engineer

No decurso de muitas entrevistas, reparei que mesmo os programadores experientes têm dificuldade em distinguir os Hooks, já para não falar das suas capacidades mais avançadas. Por isso, vou tentar explicar neste artigo como os Hooks devem ser usados.

Os aspectos mais importantes a ter em conta sobre os ganchos:

  • só podem ser utilizados em componentes de função - os componentes de classe têm a sua própria implementação do ciclo de vida;
  • começam sempre por utilização;
  • pode utilizar os Hooks que quiser, mas não se esqueça de que a sua utilização tem um impacto no desempenho geral;
  • têm de ser executados pela mesma ordem em cada renderização... mas porquê? Vamos dar uma olhada em um exemplo:
import { useState,useEffect } from "reagir";

export default function FunctionComponent() {
const [value, setValue] = useState(1);
const [doubleValue, setDoubleValue] = useState(1);
se (valor > 3) {
  useEffect(() => setDoubleValue(value * 2),[value]);
}

return (
  
    

{`Single ${value} Double ${doubleValue}`}

); } ```

No início, receberá um aviso do eslint:

<code>srcFunctionComponent.js
   Linha 11:5: React O gancho "useEffect" é chamado condicionalmente. <strong>Ganchos React</strong> devem ser chamados exatamente na mesma ordem em cada componente render .eslintreact-hooks/rules-of-hooks

Como pode ver, é apenas um aviso do eslint, pelo que pode desactivá-lo adicionando um comando a partir de baixo no topo do ficheiro FunçãoComponente

/* eslint-disable react-hooks/rules-of-hooks */ 

e vai funcionar, mas só até cumprirmos a condição que executa o nosso Hook. A próxima coisa que veremos é este erro.

Erro não detectado: Renderizou mais ganchos do que na renderização anterior.
     React 5
     FunctionComponent FunctionComponent.js:11
     React 12
     unstable_runWithPriority scheduler.development.js:468
     React 17
     js index.js:7
     js main.chunk.js:905
     Webpack 7
 react-dom.development.js:15162

Por que isso acontece? O React se baseia na ordem em que os Hooks são chamados, pois o React não saberia o que retornar para o useEffect porque não havia tal Hook na linha para verificar.

Lembre-se, o eslint é uma ferramenta poderosa, que ajuda nós captura muitos erros e bugs potenciais. Desativar os avisos é perigoso. Verifique sempre se ignorar o aviso pode causar uma falha na aplicação.

useState

Provavelmente já sabes como é que fica 😉

const [value, setValue] = useState(0);

Assim, tem 4 elementos: estado (valor reativo), função de atualização (setter), gancho real (função) e valor inicial opcional. Porque é que retorna um array? Porque podemos reestruturá-lo como quisermos.

Agora quero concentrar-me no último elemento - o valor inicial. Há duas maneiras de passar o estado inicial:

  1. Por um valor codificado ou algo do género - que será chamado em cada renderização
const [value, setValue] = useState(0);
  1. Por uma versão de função. É realmente útil se quisermos executar o estado inicial apenas uma vez, na primeira renderização. Talvez seja necessário fazer muitos cálculos complexos para receber o estado inicial? Isso vai diminuir bastante o custo de recursos, yay!
const [value, setValue] = useState(() => {
   consola.log("INIT");
   return 0;
 });

Como verificar se a primeira forma é realmente chamada em cada renderização? Crie uma função e passe-a como um estado inicial:

const checkInit = () => {
console.log("INIT");
return 0;
};

const [value, setValue] = useState(checkInit());
```

E agora passe-o utilizando a segunda via:

const checkInit = () => {
console.log("INIT");
return 0;
};

const [value, setValue] = useState(() => checkInit());
```

Fixe, não é?

ruído.png

Outra coisa que pode criar erros no fluxo da aplicação: provavelmente sabe como atualizar um estado, certo?

setValue(1);

Certo... mas e se eu quiser atualizar o estado com base num estado anterior?

setValue(value + 1);

Sim... Mas não... E se tentar chamar a função setter duas vezes, uma após a outra? A forma recomendada de atualizar um estado com base no estado anterior é utilizar uma função. Esta garante que se está a referir ao estado anterior

setValue((prevState) => prevState + 1);
// com objectos:
setUser((prevState) => ({ ...prevState, lastName: "Brzeczyszczykiewicz" }));

useEffect

Este Hook recebe 2 argumentos (o segundo é opcional) e usamo-lo para lidar com efeitos secundários. E dependendo do que passarmos como segundo argumento, o Hook será chamado de forma diferente:

  1. sem segundo argumento - cada renderização
useEffect(() => {
   doSomething();
 });
  1. matriz vazia - apenas na primeira apresentação
useEffect(() => {
   doSomething();
 }, []);
  1. matriz com dependências - sempre que o valor na matriz de dependências muda
useEffect(() => {
   doSomething(value);
 }, [valor]);

Limpeza

Com o useEffect, podemos utilizar algo a que chamamos limpeza. Para que é que serve? É muito útil, mas acho que é melhor para limpar ouvintes de eventos. Digamos que você queira criar um event listener que depende de algum estado. Você não quer adicionar um novo event listener a cada mudança de estado, porque depois de algumas renderizações haverá tantos listeners que isso afetará o desempenho da aplicação. Uma ótima maneira de evitar essas coisas é usar o recurso de limpeza. Como fazer isso? Basta adicionar uma função de retorno ao useEffect.

useEffect(() => {
consola.log("efeito secundário 1", contagem);
return () => {
console.log("DESTROYED 1");
};
});

useEffect(() => {
console.log("efeito colateral 2", count);
return () => {
console.log("DESTROYED 2");
};
}, []);

useEffect(() => {
consola.log("efeito secundário 3", contagem);
return () => {
console.log("DESTROYED 3");
};
}, [count]);
```

Porque está dentro do Hook useEffect, o retorno é chamado dependendo do array de dependências - em cada renderização, apenas na primeira renderização, ou quando o valor no array de dependências muda. Mas quando o componente é desmontado, cleaning será chamado no segundo argumento, não importa o que aconteça. O retorno código é chamado antes do código real do Hook. É muito lógico - primeiro limpar o antigo, depois criar um novo. Certo?

useEffect(() => {
   // addEventListener
   console.log("Add");
   return () => {
     // removeEventListener
     console.log("Remove");
   };
 }, [value]);

Assim, em primeiro lugar, receberá um remover mensagem, então Adicionar.

Há uma coisa a ter em atenção quando se utiliza useEffect e código assíncrono dentro dele. Dê uma olhada no código abaixo:

useEffect(() => {
   fetch("https://picsum.photos/5000/5000").then(() => {
     setValue((prevState) => prevState + 1);
   });
 }, []);

No início, parece estar tudo bem. Está a obter alguns dados e, quando os dados chegam, actualiza o estado. E aqui está a armadilha:

Por vezes, recebe um aviso deste tipo:
Não é possível efetuar uma atualização de estado do React num componente não montado. Isto não é uma opção, mas indica uma fuga de memória na sua aplicação. Para corrigir, cancele todas as assinaturas e tarefas assíncronas em uma função de limpeza useEffect.

A razão é que o componente pode ser desmontado entretanto, mas a aplicação continuará a tentar atualizar o estado desse componente depois de a promessa ter sido cumprida. Como lidar com isso? É necessário verificar se o componente existe.

useEffect(() => {
let mounted = true;
fetch("https://picsum.photos/5000/5000").then(() => {
if (mounted) {
setValue((prevState) => prevState + 1);
}
});

return () => {
mounted = false;
};
}, []);
```

Nota: Existe um Hook muito semelhante => useLayoutEffect() - a chamada de retorno é executada após a renderização do componente, mas antes de o dom ser atualizado visualmente. É útil quando se trabalha com getBoundingClientRect(), mas deve usar useEffect por defeito. Porquê? Porque pode bloquear as actualizações visuais - quando tem um código complexo dentro do seu efeito Hook.

useContext

Para que serve? Partilhar dados sem passar props. É composto pelos seguintes elementos:

  1. Contexto criado - dados
  2. Fornecedor de contexto - fornecer contexto a todas as crianças
  3. Valor transmitido - dados que pretende partilhar
  4. Hook - para ler dados partilhados
const user = {
nome: "Adam",
lastName: "Kowalski",
};

export const UserContext = createContext(user);

;
```

Em child, é necessário importar o contexto e chamar o Hook useContext e passar esse contexto como argumento.

importar { UserContext } de "./App";

const { name } = useContext(UserContext);

retornar <h1>Olá {nome}<>
```

Voilà. Parece fixe. Principalmente para passar dados globais como temas, etc. Não recomendado para uso em tarefas com mudanças muito dinâmicas.

É claro que podemos criar um provedor de contexto personalizado e um Hook personalizado para reduzir o boilerplate... mas tratarei dos Hooks personalizados no próximo artigo.

useReducer

Permite-nos gerir o estado e voltar a renderizar quando o estado muda - como useState. É semelhante ao redução reducer. Este é melhor do que useState quando a lógica de estado é mais complicada.

const [state, dispatch] = useReducer(reducer, initialArg); 
  • Devolve o estado atual com um método de envio.
  • Diferentemente do que acontece no redux, o valor inicial é especificado quando o Hook é chamado.

Há também um terceiro argumento que pode ser passado para o useReducer - a função init.

const [state, dispatch] = useReducer(reducer, initialArg, init);

Para que é que serve? Pode ser utilizado quando queremos repor o estado no seu valor inicial. Abaixo pode encontrar um bom exemplo:

// Pai
// Criança
function init(initialNumber) {
return { number: initialNumber };
}

function reducer(state, action) {
switch (action.type) {
case "change":
return { number: Math.random() };
case "reset":
return init(action.payload);
por defeito:
throw new Error();
}
}

export default function ChildComponent({ getFactorial }) {
const [state, dispatch] = useReducer(reducer, initialNumber, init);

return (
<>
   <h2>Número: {state.number}</h2>
      <button
        onclick="{()" > dispatch({ type: "reset", payload: initialNumber })}
      &gt;
        Repor
      </button>
      <button onclick="{()" > dispatch({ type: "change" })}&gt;Draw</button>
    </>
  );
}

Número: {state.number}

ReducerInit.png

useCallback

Quando a utilizar? Quando queremos obter igualdade referencial (reduzindo assim o número de funções criadas). Este Hook devolve a função, ao contrário de useMemo que devolve o valor.

Exemplo: Criar uma função no componente principal e depois passá-la através de props

// Pai
 const getSquaredValue = () => count * count;
 ...
 return (
   
 )

Em seguida, verifique no componente filho quantas vezes o efeito Hook será chamado depois de adicionar essa função à matriz de dependências:

// Criança
 useEffect(() => {
   console.log("getSquaredValue", getSquaredValue());
 }, [getSquaredValue]);

Ele será registado na consola em cada renderização! Mesmo que os valores dentro do getSquaredValue() não foi alterada. Mas podemos evitar isso envolvendo essa função em useCallback

const getSquaredValue = useCallback(() => count * count, [count])

Também podemos passar alguns parâmetros para esta função:

const getSquaredValue = useCallback(
   (multiplicador) => contagem * contagem * multiplicador,
   [count]
 );

useMemo

const memoizedValue = useMemo(() => {
   return doSomething(value);
 }, [valor]);
  • Não é neutro quando se olha para os custos dos recursos - useMemo deve ser chamado em cada renderização, guarda o valor na memória e compara (sobrecarga de memória),
  • utiliza Memoization - a técnica de otimização, forma específica de caching.

Deve ser utilizado apenas em 2 cenários:

  1. Se quiser evitar chamar um código complexo em cada processamento;
  2. Se pretender obter uma igualdade referencial.

Vamos ver um pouco mais de perto o segundo caso. Queremos usar useEffect com um objeto como dependência. Como os objetos são comparados por sua referência, useEffect será chamado em cada renderização. Para evitar isso, podemos combinar useEffect com useMemo para memorizar esses objetos e então passar esses objetos memorizados para o array de dependências. Um pequeno exemplo:

Primeiro, tente fazê-lo sem o useMemo:

const hobbit = { name: "Bilbo" };

useEffect(() => {
consola.log("Olá ", hobbit.name);
}, [hobbit]);
```

Além disso, receberá um aviso:

O objeto 'hobbit' faz com que as dependências do gancho useEffect (linha 49) mudem em cada renderização. Mova-o para dentro do retorno de chamada useEffect. Em alternativa, envolva a inicialização de 'hobbit' no seu próprio Gancho useMemo ().eslintreact-hooks/exhaustive-deps

Em seguida, experimente usar o useMemo:

const hobbit = useMemo(() => {
return { name: "Bilbo" };
}, []);

useEffect(() => {
consola.log("Olá ", hobbit.name);
}, [hobbit]);
```

useRef

A coisa mais importante: useRef não desencadeia a re-renderização (como useState) porque não está ligado ao ciclo de renderização - mantém a mesma referência entre renders.

const ref = useRef(0);

Para chamar o valor guardado, é necessário utilizar uma propriedade atual (ref é um objeto) - ref.atual

O segundo caso para o qual podemos usar esse Hook é para referenciar elementos dentro do HTML. Cada elemento tem um atributo ref. Assim, podemos lidar com foco, eventos etc.

O terceiro caso é que podemos utilizar refs para lidar com componentes não controlados. Pode ler mais sobre eles em documentos react,
mas, resumidamente, é assim:

export default function UncontrolledForm() {
  const input = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(input.current.value);
  };

  return (
    
      
      
    
  );
}

Como pode ver, não há nenhum manipulador de eventos, ele apenas se lembra do valor digitado. É ótimo para lidar com formulários básicos quando apenas se pretende ler os valores guardados quando se precisa deles (como quando se submete).

Bónus: É ótimo quando é necessário recordar valores de estados anteriores. Você pode usar para isso o Hook useEffect, basta passar o estado para o ref.

const [value, setValue] = useState("");

let prevValue = useRef("");

useEffect(() => {
  prevValue.current = value;
}, [value]);

 setValue(e.target.value)}>;

Como pode ver, os Hooks não são assim tão óbvios. Podemos combiná-los para resolver muitos problemas. O estudo deste tema vai certamente trazer-lhe grandes benefícios.

E há também ganchos personalizados...

Em conclusão, Ganchos React revolucionaram a forma como Desenvolvedores React abordagem de construção aplicações web . Ao proporcionar uma forma mais intuitiva e eficiente de gerir o estado e o ciclo de vida dos componentes funcionais, os hooks tornaram-se parte integrante da Desenvolvimento do React .

Quer seja um programador experiente ou esteja apenas a começar com o React, é crucial compreender os hooks mais populares e os seus casos de utilização. Com ganchos como useState, useEffect, useContext, e mais, Componentes do React pode ser construído com um código mais limpo e reutilizável. Além disso, a capacidade de criar ganchos personalizados permite que os programadores encapsulem e partilhem a lógica entre vários componentes, promovendo a reutilização e a modularidade do código. À medida que o React continua a evoluir e a introduzir novas funcionalidades, os hooks desempenharão, sem dúvida, um papel central no aproveitamento de todo o potencial da estrutura.

Assim, quer esteja a trabalhar numa pequena aplicação funcional ou numa aplicação Web de grande escala, abraçar Ganchos React irá melhorar o seu fluxo de trabalho de desenvolvimento e desbloquear uma infinidade de possibilidades para criar aplicações robustas e ricas em funcionalidades Aplicações React .

Fim da Parte 1

Ler mais:

JavaScript está completamente morto. Um gajo qualquer na Internet

Implantar a API GraphQL/MongoDB usando as funções Netlify

Como matar um projeto com más práticas de codificação

Artigos relacionados

Ilustração de uma aplicação de cuidados de saúde para smartphone com um ícone de coração e um gráfico de saúde em ascensão, com o logótipo The Codest, representando soluções digitais de saúde e HealthTech.
Desenvolvimento de software

Softwares para o setor de saúde: Tipos, casos de uso

As ferramentas em que as organizações de cuidados de saúde confiam atualmente não se assemelham em nada às fichas de papel de há décadas atrás. O software de cuidados de saúde apoia agora os sistemas de saúde, os cuidados aos doentes e a prestação de cuidados de saúde modernos em...

OCODEST
Ilustração abstrata de um gráfico de barras em declínio com uma seta ascendente e uma moeda de ouro que simboliza a eficiência ou a poupança de custos. O logótipo The Codest aparece no canto superior esquerdo com o slogan "In Code We Trust" sobre um fundo cinzento claro
Desenvolvimento de software

Como dimensionar a sua equipa de desenvolvimento sem perder a qualidade do produto

Aumentar a sua equipa de desenvolvimento? Saiba como crescer sem sacrificar a qualidade do produto. Este guia cobre sinais de que é hora de escalar, estrutura da equipe, contratação, liderança e ferramentas - além de como o The Codest pode...

OCODEST
Desenvolvimento de software

Construir aplicações Web preparadas para o futuro: ideias da equipa de especialistas do The Codest

Descubra como o The Codest se destaca na criação de aplicações web escaláveis e interactivas com tecnologias de ponta, proporcionando experiências de utilizador perfeitas em todas as plataformas. Saiba como a nossa experiência impulsiona a transformação digital e o negócio...

OCODEST
Desenvolvimento de software

As 10 principais empresas de desenvolvimento de software sediadas na Letónia

Saiba mais sobre as principais empresas de desenvolvimento de software da Letónia e as suas soluções inovadoras no nosso último artigo. Descubra como estes líderes tecnológicos podem ajudar a elevar o seu negócio.

thecodest
Soluções para empresas e escalas

Fundamentos do desenvolvimento de software Java: Um Guia para Terceirizar com Sucesso

Explore este guia essencial sobre o desenvolvimento de software Java outsourcing com sucesso para aumentar a eficiência, aceder a conhecimentos especializados e impulsionar o sucesso do projeto com The Codest.

thecodest

Subscreva a nossa base de conhecimentos e mantenha-se atualizado sobre os conhecimentos do sector das TI.

    Sobre nós

    The Codest - Empresa internacional de desenvolvimento de software com centros tecnológicos na Polónia.

    Reino Unido - Sede

    • Office 303B, 182-184 High Street North E6 2JA
      Londres, Inglaterra

    Polónia - Pólos tecnológicos locais

    • Parque de escritórios Fabryczna, Aleja
      Pokoju 18, 31-564 Cracóvia
    • Embaixada do Cérebro, Konstruktorska
      11, 02-673 Varsóvia, Polónia

      The Codest

    • Início
    • Sobre nós
    • Serviços
    • Case Studies
    • Saber como
    • Carreiras
    • Dicionário

      Serviços

    • Aconselhamento
    • Desenvolvimento de software
    • Desenvolvimento backend
    • Desenvolvimento de front-end
    • Staff Augmentation
    • Programadores de back-end
    • Engenheiros de nuvem
    • Engenheiros de dados
    • Outros
    • Engenheiros de GQ

      Recursos

    • Factos e mitos sobre a cooperação com um parceiro externo de desenvolvimento de software
    • Dos EUA para a Europa: Porque é que as empresas americanas decidem mudar-se para a Europa?
    • Comparação dos centros de desenvolvimento da Tech Offshore: Tech Offshore Europa (Polónia), ASEAN (Filipinas), Eurásia (Turquia)
    • Quais são os principais desafios dos CTOs e dos CIOs?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Direitos de autor © 2026 por The Codest. Todos os direitos reservados.

    pt_PTPortuguese
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese es_ESSpanish nl_NLDutch etEstonian elGreek cs_CZCzech pt_PTPortuguese