"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como otimizei chamadas de API em meu aplicativo React

Como otimizei chamadas de API em meu aplicativo React

Publicado em 2024-11-07
Navegar:981

How I Optimized API Calls by  in My React App

Como desenvolvedores do React, frequentemente enfrentamos cenários em que várias mudanças rápidas de estado precisam ser sincronizadas com uma API. Fazer uma chamada de API para cada pequena alteração pode ser ineficiente e desgastante tanto para o cliente quanto para o servidor. É aqui que entram em jogo a rejeição e a gestão inteligente do estado. Neste artigo, construiremos um gancho React personalizado que captura chamadas paralelas de atualização de API, mesclando cargas úteis e eliminando a chamada de API.

O problema

Imagine um campo de entrada onde os usuários possam ajustar configurações ou preferências. Cada pressionamento de tecla ou ajuste pode acionar uma chamada de API para salvar o novo estado. Se um usuário fizer várias alterações em rápida sucessão, isso poderá levar a uma enxurrada de solicitações de API:

  • Uso ineficiente de recursos de rede.
  • Potenciais condições de corrida.
  • Carga desnecessária no servidor.

Entre no Debouncing

Debouncing é uma técnica usada para limitar a taxa na qual uma função pode disparar. Em vez de chamar a função imediatamente, você espera um certo período de inatividade antes de executá-la. Se outra chamada for recebida antes do término do atraso, o cronômetro será zerado.

Por que usar o Debouncing?

  • Melhoria de desempenho: Reduz o número de chamadas de API desnecessárias.
  • Otimização de recursos: Minimiza a carga do servidor e o uso da rede.
  • Experiência de usuário aprimorada: evita atrasos e possíveis erros de chamadas rápidas e sucessivas.

O papel de useRef

No React, useRef é um gancho que permite persistir valores mutáveis ​​entre renderizações sem acionar uma nova renderização. É essencialmente um contêiner que contém um valor mutável.

Por que usar useRef aqui?

  • Persistir atualizações acumuladas: Precisamos acompanhar as atualizações acumuladas entre renderizações sem causar novas renderizações.
  • Acessar valor atual mutável: useRef nos fornece uma propriedade .current que podemos ler e escrever.

O gancho useDebouncedUpdate

Vamos mergulhar no código e entender como tudo funciona.

import { debounce } from "@mui/material";
import { useCallback, useEffect, useRef } from "react";

type DebouncedUpdateParams = {
  id: string;
  params: Record;
};

function useDebouncedUpdate( apiUpdate: (params: DebouncedUpdateParams) => void,
  delay: number = 300, ) {
  const accumulatedUpdates = useRef(null);

  const processUpdates = useRef(
    debounce(() => {
      if (accumulatedUpdates.current) {
        apiUpdate(accumulatedUpdates.current);
        accumulatedUpdates.current = null;
      }
    }, delay),
  ).current;

  const handleUpdate = useCallback(
    (params: DebouncedUpdateParams) => {
      accumulatedUpdates.current = {
        id: params.id,
        params: {
          ...(accumulatedUpdates.current?.params || {}),
          ...params.params,
        },
      };
      processUpdates();
    },
    [processUpdates],
  );

  useEffect(() => {
    return () => {
      processUpdates.clear();
    };
  }, [processUpdates]);

  return handleUpdate;
}

export default useDebouncedUpdate;

Dividindo

1. Acumulando atualizações com useRef

Inicializamos um useRef chamado acumuladoUpdates para armazenar os parâmetros combinados de todas as atualizações recebidas.

const Atualizações acumuladas = useRef(nulo);

2. Debounce da chamada de API

Criamos uma função processUpdates debounce usando o utilitário debounce do Material UI.

const processUpdates = useRef(
  debounce(() => {
    if (accumulatedUpdates.current) {
      apiUpdate(accumulatedUpdates.current);
      accumulatedUpdates.current = null;
    }
  }, delay),
).current;
  • Por que useRef para processUpdates? Usamos useRef para garantir que a função debounce não seja recriada em cada renderização, o que redefiniria o temporizador de debounce.

3. Tratamento de atualizações com useCallback

A função handleUpdate é responsável por acumular atualizações e acionar a chamada de API debounce.

const handleUpdate = useCallback(
  (params: DebouncedUpdateParams) => {
    accumulatedUpdates.current = {
      id: params.id,
      params: {
        ...(accumulatedUpdates.current?.params || {}),
        ...params.params,
      },
    };
    processUpdates();
  },
  [processUpdates],
);
  • Mesclando parâmetros: mesclamos os novos parâmetros com quaisquer parâmetros existentes para garantir que todas as atualizações sejam capturadas.
  • Trigger Debounce: Cada vez que handleUpdate é chamado, acionamos processUpdates(), mas a chamada de API real é debounce.

4. Limpeza com useEffect

Limpamos a função debounce quando o componente é desmontado para evitar vazamentos de memória.

useEffect(() => {
  return () => {
    processUpdates.clear();
  };
}, [processUpdates]);

Como funciona

  1. Parâmetros acumulados: Cada atualização adiciona seus parâmetros a acumuladoUpdates.current, fundindo-se com quaisquer parâmetros existentes.
  2. Debounce Execution: processUpdates aguarda um atraso de milissegundos de inatividade antes de executar.
  3. Chamada de API: Depois de decorrido o tempo de depuração, apiUpdate é chamado com os parâmetros mesclados.
  4. Redefinir atualizações acumuladas: Após a chamada da API, redefinimos acumuladoUpdates.current para nulo.

Exemplo de uso

Veja como você pode usar esse gancho em um componente:

import React from "react";
import useDebouncedUpdate from "./useDebouncedUpdate";

function SettingsComponent() {
  const debouncedUpdate = useDebouncedUpdate(updateSettingsApi, 500);

  const handleChange = (settingName, value) => {
    debouncedUpdate({
      id: "user-settings",
      params: { [settingName]: value },
    });
  };

  return (
    
handleChange("username", e.target.value)} /> handleChange("notifications", e.target.checked)} />
); } function updateSettingsApi({ id, params }) { // Make your API call here console.log("Updating settings:", params); }
  • Ações do usuário: À medida que o usuário digita ou alterna as configurações, handleChange é chamado.
  • Atualizações rejeitadas: As alterações são acumuladas e enviadas para a API após 500 ms de inatividade.

Conclusão

Ao combinar o debouncing com a acumulação de estado, podemos criar aplicativos eficientes e responsivos. O gancho useDebouncedUpdate garante que mudanças rápidas sejam agrupadas em lote, reduzindo chamadas de API desnecessárias e melhorando o desempenho.

Principais conclusões:

  • Debouncing é essencial para gerenciar chamadas rápidas e sucessivas.
  • useRef nos permite manter um estado mutável sem causar novas renderizações.
  • Ganchos personalizados como useDebouncedUpdate encapsulam lógica complexa, tornando os componentes mais limpos e fáceis de manter.

Sinta-se à vontade para integrar este gancho em seus projetos e ajustá-lo para atender às suas necessidades específicas. Boa codificação!

Declaração de lançamento Este artigo está reproduzido em: https://dev.to/marrouchi/how-i-did-optimize-by-40-api-calls-in-my-react-app-23od?1 Se houver alguma violação, por favor entre em contato com study_golang@163 .comdelete
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3