DEV Community

Cover image for Stop Suffering from Prop Drilling: See 5 Tips that Can Save Your Code
Werliton Silva
Werliton Silva

Posted on

Stop Suffering from Prop Drilling: See 5 Tips that Can Save Your Code

O problema: o que é prop drilling?

"Prop drilling" (ou "perfuração de props") é o processo de passar dados de um componente pai para um filho, depois para um neto, bisneto, tataraneto, e assim por diante, até que a prop chegue no componente que realmente precisa dela. Isso pode se tornar repetitivo e difícil de manter à medida que a árvore de componentes cresce.

Exemplo prático de prop drilling

function App() {
  const msg = "Passei pelo Header e pelo Wrapper e cheguei no Button!";
  return <Main msg={msg} />;
}

function Main({ msg }) {
  return <Header msg={msg} />;
}

function Header({ msg }) {
  return (
    <div>
      <h1>Header aqui</h1>
      <Wrapper msg={msg} />
    </div>
  );
}

function Wrapper({ msg }) {
  return (
    <div>
      <h2>Wrapper aqui</h2>
      <Button msg={msg} />
    </div>
  );
}

function Button({ msg }) {
  return (
    <div>
      <h3>Componente Button</h3>
      <button onClick={() => alert(msg)}>Clique em mim!</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

A mensagem precisa ser usada no componente Button, mas foi passada através de Main, Header e Wrapper, que não a utilizam de fato. Esse é o clássico caso de prop drilling.


Soluções para evitar o prop drilling

1. Context API

A Context API é nativa do React e permite compartilhar dados com múltiplos componentes sem precisar passar props manualmente em cada nível.

import { createContext, useContext } from 'react';

const MessageContext = createContext();

function App() {
  const msg = "Passei pelo contexto até chegar no Button!";
  return (
    <MessageContext.Provider value={msg}>
      <Main />
    </MessageContext.Provider>
  );
}

function Main() {
  return <Header />;
}

function Header() {
  return (
    <div>
      <h1>Header aqui</h1>
      <Wrapper />
    </div>
  );
}

function Wrapper() {
  return (
    <div>
      <h2>Wrapper aqui</h2>
      <Button />
    </div>
  );
}

function Button() {
  const msg = useContext(MessageContext);
  return (
    <div>
      <h3>Componente Button</h3>
      <button onClick={() => alert(msg)}>Clique em mim!</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

2. Usando Jotai

Jotai

Jotai é uma biblioteca de gerenciamento de estado para React, leve e baseada em átomos. É uma alternativa moderna à Context API e evita prop drilling de forma elegante.

Instalação

npm install jotai
Enter fullscreen mode Exit fullscreen mode

Exemplo com Jotai

import { atom, useAtom } from 'jotai';

// Criando o átomo (estado global)
const messageAtom = atom("Passei via Jotai e cheguei no Button!");

function App() {
  return <Main />;
}

function Main() {
  return <Header />;
}

function Header() {
  return (
    <div>
      <h1>Header aqui</h1>
      <Wrapper />
    </div>
  );
}

function Wrapper() {
  return (
    <div>
      <h2>Wrapper aqui</h2>
      <Button />
    </div>
  );
}

function Button() {
  const [msg] = useAtom(messageAtom);
  return (
    <div>
      <h3>Componente Button</h3>
      <button onClick={() => alert(msg)}>Clique em mim!</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

No exemplo acima, o valor do átomo messageAtom pode ser acessado diretamente de qualquer componente da árvore, sem precisar ser passado como prop.


3. Usando Zustand

Zustand

Zustand é uma alternativa leve para gerenciamento de estado global. Mais simples que Redux, mais direto que Context em alguns casos.

Instalação

npm install zustand
Enter fullscreen mode Exit fullscreen mode

Exemplo de uso

import create from 'zustand';

const useStore = create((set) => ({
  msg: 'Passei via Zustand!',
}));

function App() {
  return <Main />;
}

function Main() {
  return <Header />;
}

function Header() {
  return (
    <div>
      <h1>Header</h1>
      <Wrapper />
    </div>
  );
}

function Wrapper() {
  return (
    <div>
      <h2>Wrapper</h2>
      <Button />
    </div>
  );
}

function Button() {
  const msg = useStore((state) => state.msg);
  return (
    <div>
      <h3>This is the Button component</h3>
      <button onClick={() => alert(msg)}>Click me!</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Conclusão

Prop drilling é um problema comum em aplicações React mais complexas. Embora funcione bem em estruturas pequenas, conforme a aplicação cresce, o código se torna mais difícil de manter.

Felizmente, existem soluções simples para isso:

  • Context API para compartilhar valores entre vários componentes.
  • Jotai para um controle mais granular e escalável do estado.
  • Zustand é leve e direto para estados globais simples.

Escolha a abordagem que melhor se encaixa no tamanho e complexidade do seu projeto. Para projetos simples, Context pode ser suficiente. Para projetos maiores ou que exigem maior controle de estado, Jotai ou Zustand pode ser uma excelente alternativa.

Ah... e o Redux?? Tchacalma! Depois a gente fala dele. Ele tá em outra caixinha.

Curtiu o conteúdo?

Se esse artigo te ajudou a entender melhor o problema do prop drilling e como resolvê-lo com ferramentas modernas como Context, Zustand e Jotai:

⭐ Deixe seu like ou reação
💬 Comente qual solução você mais usa (ou pretende usar)
🔁 Compartilhe com seu time ou comunidade dev
📌 Me siga aqui no Dev.to (ou LinkedIn) para mais conteúdos como esse!

Top comments (2)

Collapse
 
nathan_tarbert profile image
Nathan Tarbert

Yeah this is the stuff I wish I saw when I was banging my head on passing props everywhere, loving the way you break down solutions

Collapse
 
werliton profile image
Werliton Silva

That's great! I'm glad to hear that.