What is HOC?
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
const EnhancedComponent = withSomething(BaseComponent);Here:
BaseComponentis your regular component;withSomethingis the HOC function;EnhancedComponentis the new component with added logic.
Example 1. The simplest HOC - logging a render
function withLogger(WrappedComponent) {
return function Enhanced(props) {
console.log(`Rendering component: ${WrappedComponent.name}`);
return <WrappedComponent {...props} />;
};
}Usage:
function Hello({ name }) {
return <h1>Hello, {name}</h1>;
}
const HelloWithLogger = withLogger(Hello);
// ...
<HelloWithLogger name="Alex" />;What happens:
withLoggerreturns a new component;- on every render the component's name is logged to the console;
- the original component (
Hello) receives allpropsunchanged.
Example 2. An HOC that adds data
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
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
- Do not modify the original component An HOC should wrap, not mutate the component. Bad:
WrappedComponent.prototype.newMethod = () => {}Good:
return function Enhanced() { return <WrappedComponent />; };- Pass
propsthrough Always forward...propsso you do not lose the passed properties:
return <WrappedComponent {...props} />;- Keep a readable component name HOCs often do this:
Enhanced.displayName = `withLogger(${WrappedComponent.displayName || WrappedComponent.name})`;- Do not overuse nesting Many HOCs in a row create a "pyramid":
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:
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:
// 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.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.