Blog>
Snippets

Implementing HOCs (Higher-Order Components)

Illustrate how to wrap class components in higher-order components for reusability and to abstract shared logic.
function withUserData(WrappedComponent) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.state = { userData: null };
    }

    componentDidMount() {
      this.loadData();
    }

    loadData() {
      // Assume fetchUserData is a function that fetches user data
      fetchUserData().then(data => {
        this.setState({ userData: data });
      });
    }

    render() {
      const { userData } = this.state;
      return userData ? <WrappedComponent {...this.props} userData={userData} /> : null;
    }
  };
}
This is a higher-order component (HOC) named withUserData. It takes a component (WrappedComponent) as a parameter and returns a new component class. This new class fetches user data on mount and passes that data down as a prop to the WrappedComponent once it is loaded.
class UserProfile extends React.Component {
  render() {
    // This component expects a prop named userData
    const { userData } = this.props;
    return (
      <div>
        <h1>User Profile</h1>
        <p>Name: {userData.name}</p>
        <p>Email: {userData.email}</p>
      </div>
    );
  }
}
UserProfile is a simple class component that expects to receive a userData prop and renders the user's name and email. This component does not manage or fetch its own data; it's the responsibility of the HOC to provide the required userData prop.
const EnhancedUserProfile = withUserData(UserProfile);
EnhancedUserProfile is a new component created by wrapping the UserProfile component with the withUserData HOC. This wrapped component will have the user data fetching logic applied to it, making it reusable in different parts of an application without duplicating the data fetching logic.