Skip to main content

Що таке "prop drilling"?

Визначення

Prop drilling - це процес, при якому дані (props) передаються вниз по дереву компонентів через декілька проміжних рівнів, які самі ці дані не використовують, а просто "пробрасують далі".


Простий приклад

Припустимо, у тебе є структура:

javascript
<App> └── <Parent> └── <Child> └── <Grandchild>

Ти хочеш передати дані з App -> в Grandchild.

Без контексту (через props):

javascript
function Grandchild({ user }) { return <p>Привіт, {user.name}!</p>; } function Child({ user }) { return <Grandchild user={user} />; } function Parent({ user }) { return <Child user={user} />; } export default function App() { const user = { name: "Tim" }; return <Parent user={user} />; }

Тут Parent і Child не використовують user взагалі, вони просто пробрасують його далі.

Це і є prop drilling.


Чому це погано

ПроблемаЩо відбувається
Шум у кодіКожен проміжний компонент змушений мати зайві props
Складно підтримуватиПри зміні структури - потрібно змінювати всі рівні
Знижується ізоляціяКомпоненти стають залежні від даних, яких не використовують
Перевикористовуваність падає"Дурні" компоненти змушені знати про непотрібні props
Важко читати"Ланцюжок" пропсів ускладнює розуміння логіки застосунку

Ілюстрація

javascript
App ├── user (зберігається тут) ↓ Parent ↓ Child ↓ Grandchild (використовує)

Все дерево "просвердлене" пропсами зверху вниз - звідси і термін "drilling" (свердління).


Приклад ближчий до реального

javascript
<App> <Navbar /> <Sidebar /> <Main> <PostList> <PostCard user={user} /> </PostList> </Main> </App>

Якщо user потрібен тільки в PostCard, але його потрібно передавати через Main і PostList - це вже prop drilling hell.


Як вирішити проблему prop drilling

1. React Context API

Найстандартніший спосіб позбутися свердління - створити "глобальне джерело даних".

javascript
import { createContext, useContext } from "react"; const UserContext = createContext(null); function Grandchild() { const user = useContext(UserContext); return <p>Привіт, {user.name}!</p>; } function App() { const user = { name: "Tim" }; return ( <UserContext.Provider value={user}> <Grandchild /> </UserContext.Provider> ); }

Тепер Grandchild отримує user напряму з контексту, а не через ланцюжок props.


2. State management (Redux, Zustand, Jotai, Recoil)

Якщо даних багато, і вони потрібні в різних частинах застосунку - краще винести їх у глобальне сховище:

javascript
// store.js (приклад із Zustand) import { create } from "zustand"; export const useUserStore = create(set => ({ user: { name: "Tim" }, setUser: (user) => set({ user }), })); // Grandchild.jsx import { useUserStore } from "./store"; function Grandchild() { const user = useUserStore(state => state.user); return <p>Привіт, {user.name}!</p>; }

Тепер не потрібно "свердлити" пропси - дані доступні з будь-якого компонента.


3. Custom hooks

Якщо контекст або Zustand - "важка зброя", можна просто зробити кастомний хук, щоб сховати передачу:

javascript
function useUser() { const [user, setUser] = useState({ name: "Tim" }); return { user, setUser }; } function App() { const userStore = useUser(); return <Parent userStore={userStore} />; } function Grandchild({ userStore }) { const { user } = userStore; return <p>{user.name}</p>; }

Чистіше, ніж передавати кожен окремий prop, але prop drilling залишається - просто спрощений.


4. Композиція замість props

Іноді можна передати компоненти напряму через children:

javascript
function Layout({ header, footer }) { return ( <div> <header>{header}</header> <main>Контент</main> <footer>{footer}</footer> </div> ); } function App() { return ( <Layout header={<Header user={{ name: "Tim" }} />} footer={<Footer />} /> ); }

Це не прибирає prop drilling глобально, але робить передачу даних локальною і більш керованою.


Коли prop drilling допустимий

Не завжди потрібно уникати його будь-якою ціною.

Якщо дерево компонентів неглибоке (1-2 рівні). Якщо prop потрібен тільки трохи нижче. Якщо даних небагато і вони рідко змінюються.

Контекст і стор - потрібні, коли проблема системна, а не випадкова.


Підсумок

КритерійProp drilling
Що цеПередача props через ланцюжок проміжних компонентів
Чому поганоЗабруднює код, знижує ізоляцію і перевикористовуваність
Коли допустимоДля неглибоких і простих випадків
Як вирішуватиContext API, Zustand, Redux, custom hooks
Головне правило"Якщо prop проходить через більше ніж 2 рівні - задумайся про контекст"

Головна ідея:

Prop drilling - це коли дані просвердлюються через зайві компоненти. Рішення - винести джерело даних вище і дати до нього прямий доступ.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.