Suggest an editImprove this articleRefine the answer for “What is HOC?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)A **Higher-Order Component (HOC)** is a **function** that **accepts a component as an argument** and **returns a new component**, adding extra behavior or data to it. **Key point:** an HOC is a function that wraps a component to "extend" its functionality.Shown above the full answer for quick recall.Answer (EN)Image## Short definition > A **Higher-Order Component (HOC)** is a **function**, > that **accepts a component as an argument** > and **returns a new component**, > adding extra behavior or data to it. In other words: > HOC = a function that wraps a component to "extend" its functionality. --- ## One-line example ```javascript const EnhancedComponent = withSomething(BaseComponent); ``` Here: - `BaseComponent` is your regular component; - `withSomething` is the HOC function; - `EnhancedComponent` is the new component with added logic. --- ## Example 1. The simplest HOC - logging a render ```javascript function withLogger(WrappedComponent) { return function Enhanced(props) { console.log(`Rendering component: ${WrappedComponent.name}`); return <WrappedComponent {...props} />; }; } ``` Usage: ```javascript function Hello({ name }) { return <h1>Hello, {name}</h1>; } const HelloWithLogger = withLogger(Hello); // ... <HelloWithLogger name="Alex" />; ``` What happens: - `withLogger` returns a new component; - on every render the component's name is logged to the console; - the original component (`Hello`) receives all `props` unchanged. --- ## Example 2. An HOC that adds data ```javascript function withUser(WrappedComponent) { return function Enhanced(props) { const user = { name: "Alex", role: "admin" }; return <WrappedComponent {...props} user={user} />; }; } function Profile({ user }) { return <p>User: {user.name}</p>; } const ProfileWithUser = withUser(Profile); ``` Now `ProfileWithUser` is a version of `Profile` that always receives `user` through `props`, without needing to duplicate that logic in every component. --- ## Example 3. Adding state or effects ```javascript function withWindowWidth(WrappedComponent) { return function Enhanced(props) { const [width, setWidth] = useState(window.innerWidth); useEffect(() => { const handleResize = () => setWidth(window.innerWidth); window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, []); return <WrappedComponent {...props} width={width} />; }; } function Info({ width }) { return <p>Window width: {width}px</p>; } const InfoWithWidth = withWindowWidth(Info); ``` Now `InfoWithWidth` automatically receives the current window width, and the `Info` component does not need to know how it is computed. --- ## Important HOC principles 1. **Do not modify the original component** An HOC should *wrap*, not *mutate* the component. Bad: ```javascript WrappedComponent.prototype.newMethod = () => {} ``` Good: ```javascript return function Enhanced() { return <WrappedComponent />; }; ``` 2. **Pass** `props` **through** Always forward `...props` so you do not lose the passed properties: ```javascript return <WrappedComponent {...props} />; ``` 3. **Keep a readable component name** HOCs often do this: ```javascript Enhanced.displayName = `withLogger(${WrappedComponent.displayName || WrappedComponent.name})`; ``` 4. **Do not overuse nesting** Many HOCs in a row create a "pyramid": ```javascript withTheme(withAuth(withRouter(withLogger(App)))) ``` This hurts readability and debugging. --- ## Example 4. A real case - HOC in Redux The most well-known HOC is `connect()` from **React Redux**: ```javascript import { connect } from "react-redux"; function Profile({ user }) { return <p>Hello, {user.name}</p>; } const mapState = (state) => ({ user: state.user }); export default connect(mapState)(Profile); ``` Here `connect`: - subscribes the component to the Redux store; - passes the state as `props`; - returns a **new component** that wraps `Profile`. --- ## When to use an HOC When you need to **reuse logic** between components: - authorization / access (`withAuth`) - error handling (`withErrorBoundary`) - data fetching (`withDataFetch`) - measuring window size, mouse position, and so on You should not use it: - if the same thing can be expressed with **hooks** (`useUser`, `useWindowWidth`, etc.); - when it creates a "staircase" of nested components. --- ## Modern alternative: Hooks After hooks appeared (React 16.8) HOCs are **almost always replaced by hooks**: ```javascript // Instead of an HOC const ProfileWithUser = withUser(Profile); // You can simply: function Profile() { const user = useUser(); return <p>{user.name}</p>; } ``` Hooks are simpler, more readable and do not create nested structures. --- ## Summary | What | Description | |---|---| | **HOC** | A function that accepts a component and returns a new one | | **Goal** | Add shared logic or data to a component | | **Example** | `withLogger(Component)`, `connect(mapState)(Component)` | | **Does not do** | Changes inside the original component | | **Modern alternative** | Custom hooks (`useAuth`, `useTheme`, `useUser`) | --- **Main idea:** > A **Higher-Order Component** is a "wrapper" that extends a component's capabilities, > without changing its source code. > Today HOCs are increasingly replaced by **hooks**, but the "wrapping" principle remains fundamental to React. </content>For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.