Executando verificação de segurança...
17

[REACT] Props Drilling ou Context API?

React: Context API vs Props Drilling

Esse conteúdo apresenta uma analogia visual lúdica e prática para entender como o Context API resolve o problema de props drilling no React.


🔍 Problema: Props Drilling

Imagine que você tem um dado importante (como o nome e a função que altera um produto) no Component1, mas quem realmente precisa usar esse dado está no Component3. Para isso, você é obrigado a passar os dados por todos os componentes intermediários, mesmo que eles não façam nada com eles. Vamos ao exemplo prático:

//component1.jsx

import { useState } from "react";
import Component2 from "./component2";

export default function Component1() {
  const produtoInicial = "Arroz";

  const [produtoHerdado, setProdutoHerdado] = useState(produtoInicial);

  return (
    <div>
      <h1>Armazem Props Drilling</h1>
      <Component2
        produtoHerdado={produtoHerdado}
        setProdutoHerdado={setProdutoHerdado}
      />
    </div>
  );
}


//component2.jsx

import Component3 from "./component3";

export default function Component2(props) {
  return (
    <div>
      <Component3
        produtoHerdado={props.produtoHerdado}
        setProdutoHerdado={props.setProdutoHerdado}
      />
    </div>
  );
}


//component3.jsx

export default function Component3(props) {
  return (
    <div>
      <h3>{props.produtoHerdado}</h3>
      <button
        onClick={() =>
          props.setProdutoHerdado(() =>
            props.produtoHerdado === "Arroz" ? "Feijão" : "Arroz"
          )
        }
      >
        Alterar Produto
      </button>
    </div>
  );
}

📌 Isso é o props drilling: um excesso de repasse de propriedades.


✅ Solução: Context API

Com o Context API, você pode fornecer dados globalmente a qualquer componente filho, sem precisar fazer esse repasse manual. É como se todos os componentes dentro de um “armazém” pudessem acessar e alterar diretamente os produtos guardados lá dentro.



🧠 Analogias

Conceito ReactAnalogia Visual
propsProduto e/ou função entregue manualmente
Context.ProviderArmazém com gerente
useContextRampa de acesso ao armazém
setProdutoGerente organizando os produtos
Componentes filhosClientes pegando direto no armazém

🧪 Exemplo prático com Context API

//armazemContext.jsx

import { createContext, useContext, useState } from "react";

// Criação do contexto (armazém)
const ArmazemContext = createContext();

// Provider que armazena o produto e permite alteração (gerente do armazém)
export function ArmazemProvider({ children }) {
  const [produto, setProduto] = useState("Arroz");

  return (
    // Abre as portas do armazém e disponibiliza os produtos e o gerente pra quem estiver dentro
    <ArmazemContext.Provider value={{ produto, setProduto }}>
      {children}
    </ArmazemContext.Provider>
  );
}

// Hook para acesso fácil (rampa de acesso ao armazém)
export function useArmazem() {
  return useContext(ArmazemContext);
}


//App.jsx

import { ArmazemProvider } from "./context/armazemContext";
import "./index.css";

import ComponentContext1 from "./context/componentContext1";

function App() {
  return (
    <div>
      <h1>React (Props Drilling Vs Context API)</h1>
      <ArmazemProvider>
        <ComponentContext1 />
      </ArmazemProvider>
    </div>
  );
}

export default App;


//componentContext1.jsx

import ComponentContext2 from "./componentContext2";
import ComponentContext3 from "./componentContext3";

export default function ComponentContext1() {
  return (
    <div>
      <h1>Armazem Context API</h1>
      <ComponentContext2 />
      <ComponentContext3 />
    </div>
  );
}


//componentContext2.jsx

import { useArmazem } from "./armazemContext";

export default function ComponentContext2() {
  const { produto } = useArmazem();
  return (
    <div>
      <h3>{produto}</h3>
    </div>
  );
}


//componentContext3.jsx

import { useArmazem } from "./armazemContext";

export default function ComponentContext3() {
  const { produto, setProduto } = useArmazem();
  return (
    <div>
      <button
        onClick={() => setProduto(produto === "Arroz" ? "Feijão" : "Arroz")}
      >
        Alterar Produto
      </button>
    </div>
  );
}

💡 Dica: Clone o projeto, altere os produtos, adicione temas ou autenticação, e pratique compondo contextos reais!

Este conteúdo foi criado com o intuito de ser lúdico e simples, facilitando o entendimento para quem tem dificuldades com Context API ou para aspirantes no universo do React.

Repositório do "Projeto":
react-drilling-vs-context

😄 Obrigado pela leitura!

Carregando publicação patrocinada...
4

Esse assunto é interessante que ilustra bem aquilo que para mim é o maior desafio da programação, que é escolher entre duas alternativas que possui seus prós e contras.

O propdrilling não é um problema em si. Já vi algumas pessoas dizendo que é aceitável o propdrilling até 3º nível (pai -> filho -> neto) - ou mais, em projetos simples. Aí a pergunta muda: o que é um projeto simples? Em contrapartida, o context API também traz complexidade para o desenvolvimento.

Por essa razão eu gosto de uma abordagem que consiste em desenvolver do simples para o complexo. Tirando situações óbvias em que você já sabe que vai precisar compartilhar dados por diversos pontos da árvore, eu iniciaria com o prop drilling. Havendo a necessidade, refatore.

No fundo, uma boa organização com composição de componentes ajuda muito, entendendo o uso do context API quando for realmente necessário passar dados em muitos níveis da árvore do react.

1

Concordo com isso. Faça o simples. Se precisar implemente melhorias. Quando é até 2 componentes e sei que não irá estender no futuro eu opito pelos props. Mas nesse exemplo, tento trazer a analogia com 3 components, mesmo sabendo que só precisaria de 2 ou 1, justamente para conseguir exemplificar de forma simples. Obrigado pelo feed. Vou tentar melhorar esse conteúdo.

4

Muito bom! Mas acho que o titulo deveria ser: Como resolver problema de props drilling ou como implementar context api. Ou até uma abordagem onde justifique usar o context api e onde não justifica. Mas com certeza ficou clara a utilização do context api.

1

Obrigado, pelo feedback. Talvez eu reveja esse conteúdo e tente organizar de uma meneira melhor. Como para agente é algo que pode parecer simples. As vezes fica difícil parar para pensar nessas analogias... rsrsrs

1

Hoje em dia nem considero context como uma alternativa, já que há dezenas de opções melhores como Zustand, Recoil... Ainda acho válido context para alguns contextos como tema, mas de maneira geral, é difícil manter uma boa arquitetura no projeto usando apenas context.

1

Boa zustend é top. E você está coberto de razão. Na prática para quem também está lendo isso vai algumas ideias de casos de uso. Se o que você quer usar não muda tanto, como um tema, idioma, autenticação, coisas do tipo. Vá de ContextAPI. Porque é leve nativo e sem dependências externas. Mas em contra partida se você precisa atualizar estados globais dinâmicos que mudam com muita frequencia. Vá de zustend. Porque o ContextAPI ao mudar um estado global, renderiza todos os components que o consomem de novo, o famoso "re-render". Já o zustend não gera essas renderizações desnecessárias e é de fácil utilização. Eu o usaria em carrinho de compras, formulários complexos, filtros dinâmicos, dashboards, etc. Espero que complemente o conteúdo do amigo a cima e ajude de alguma forma.