A Higher-Order Component (HOC) is an advanced technique for reusing component logic. HOCs are not part of the React API, but rather a pattern that emerges from React’s compositional nature.
A higher-order component is a function that takes a component as an argument and returns a new component that wraps the original component
This allows you to add additional functionality to the component without modifying its original code. HOCs are commonly used to share common functionality between multiple components, such as state modification or props change.
1. Creating a Higher-Order Component:
import React from 'react';
// This is the HOC function
function withCounter(WrappedComponent) {
class WithCounter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
handleIncrement = () => {
this.setState((prevState) => {
return { count: prevState.count + incremntNuber };
});
};
render() {
return (
<WrappedComponent
count={count}
incrementHandler={this.handleIncrement}
{...this.props}
/>
);
}
}
return WithCounter;
}
2. Using the HOC:
// A simple component
function MyComponent(props) {
return (
<button onClick={props.incrementHandler}>
{props.name} Click {props.count} times
</button>
);
}
// Wrap the component with the HOC
const EnhancedComponent = withCounter(MyComponent);
// Usage
function App() {
return <EnhancedComponent name="Hello World!" />;
}
In this example, withCounter is the HOC that adds some extra information to the MyComponent component. When EnhancedComponent is used, it renders MyComponent with the original props along with the additional paragraph containing "Some extra information".
3. Key Points About HOCs:
Pure Functions: HOCs should be pure, meaning they should not modify the original component. Instead, they should create a new component that wraps the original one.
Props Proxy: HOCs can pass props to the wrapped component. This pattern is useful for injecting additional props or modifying existing ones before passing them down.
Composability: HOCs can be composed. You can create multiple HOCs and apply them to a component sequentially.
Convention: It's a common convention to name HOCs with a prefix like with, such as withRouter or withUser, to indicate that it's an HOC.
Static Methods: HOCs do not copy static methods from the wrapped component. If the wrapped component has static methods that need to be accessed, you’ll need to manually copy them.
Here’s an example of ensuring static methods are preserved:
import React from 'react';
// Helper function to copy static methods
function hoistStatics(targetComponent, sourceComponent) {
const keys = Object.getOwnPropertyNames(sourceComponent);
keys.forEach(key => {
if (!targetComponent.hasOwnProperty(key)) {
targetComponent[key] = sourceComponent[key];
}
});
return targetComponent;
}
function withExtraInfo(WrappedComponent) {
class HOC extends React.Component {
render() {
return (
<div>
<WrappedComponent {...this.props} />
<p>Some extra information</p>
</div>
);
}
}
// Copy static methods
hoistStatics(HOC, WrappedComponent);
return HOC;
}
Conclusion:
HOCs are a powerful pattern in React for reusing component logic, but they should be used judiciously to avoid overly complex component hierarchies.
Top comments (0)