跪拜 Guibai
← All articles
Frontend · JavaScript · React.js

Context and Custom Hooks Are React's Answer to Prop Drilling and Logic Sprawl

By dzhd ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Prop Drilling and scattered side-effect logic are the two biggest sources of brittle React codebases. Context plus custom Hooks provide a built-in escape hatch that works without pulling in Redux or other state-management libraries for many common cases.

Summary

Props Drilling forces intermediate components to ferry data they never use. Context solves this by creating a data pipeline that any descendant can tap into, regardless of nesting depth. Under the hood, `useContext` walks the Fiber tree upward to find the nearest matching Provider, and every consumer re-renders when that Provider's value reference changes.

Custom Hooks take this further by bundling Context consumption, state, and side effects into a single call. A `useMouse` Hook, for instance, hides all the `useState`, `useEffect`, and event-listener wiring behind a clean `{ x, y }` return value. The component never touches browser APIs directly.

Because browser APIs like `addEventListener` live outside React's DOM management, every effect that creates a resource must return a cleanup function. Skipping this leaves timers running, event handlers holding closures, and Web Workers consuming CPU after the component is gone. The cleanup function runs before the next effect execution or on unmount, keeping creation and destruction paired.

Takeaways
`createContext` declares a data pipeline; `Provider` injects a value into the Fiber tree; `useContext` retrieves it by walking up to the nearest matching Provider.
All consumers of a Context re-render when the Provider's value reference changes, so passing inline object literals as values causes unnecessary re-renders.
Custom Hooks can call `useState`, `useEffect`, and other Hooks, making them the only way to reuse stateful, side-effect-bearing logic across components.
Browser APIs like `addEventListener`, `setInterval`, and Web Workers are outside React's control and must be manually cleaned up in a useEffect return function.
React calls the previous effect's cleanup function before running a new effect (on dependency change) or before unmounting, ensuring resources are always destroyed.
A `hooks/` directory for logic and a `components/` directory for views creates a clear separation of concerns that scales across a codebase.
Conclusions

The article's explanation of Context's underlying mechanism — a linked list on the Fiber node — demystifies why nested Providers work and why the nearest one wins, which is rarely spelled out in introductory material.

Framing custom Hooks as 'regular functions plus access to React's reactive system' is a precise mental model that clarifies why the `use` prefix matters beyond linting: it signals that the function participates in React's state and effect lifecycle.

The warning about object literals in Provider values is a concrete, high-impact performance detail that many developers learn only after debugging mysterious re-render loops.

Concepts & terms
Props Drilling
The pattern of passing props through multiple intermediate components that don't need the data, solely to reach a deeply nested descendant. It makes refactoring harder and clutters component interfaces.
Fiber Tree
React's internal representation of the component tree, where each node (Fiber) holds state, props, and links to parent/child/sibling nodes. Context lookup traverses this tree upward from the consuming component.
useEffect Cleanup Function
A function returned from a useEffect callback that React calls before the next effect runs or before the component unmounts. It is the designated place to remove event listeners, clear timers, and terminate external resources.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗