Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке "prop drilling"?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Prop drilling** - це процес, при якому дані (`props`) передаються вниз по дереву компонентів через декілька проміжних рівнів, які самі ці дані не використовують, а просто "пробрасують далі". **Ключове:** якщо prop проходить через більше ніж 2 рівні - варто задуматися про контекст.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Визначення **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** - це коли дані просвердлюються через зайві компоненти. > Рішення - винести джерело даних вище і дати до нього прямий доступ.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.