Higher Order Component

  1. Introduction
    A Higher-Order Component (HOC) in React is a pattern used to share common functionality between components without repeating code. An HOC is a function that takes a component and returns a new component with additional props or behaviors.
    Basic Structure,
    higherOrderComponent is a function that takes a component (WrappedComponent) and returns a new component (EnhancedComponent).

     const EnhancedComponent = higherOrderComponent(WrappedComponent);
    
  2. HOC Key Points to Remember
    i) HOCs don’t modify the original component: It wraps original component and enhances it with extra functionality.

    ii) Composition over Inheritance: HOCs promote the use of composition to share functionality, which is more flexible than inheritance.

    iii) Naming Conventions: HOCs usually follow the naming convention of withSomething or enhanceSomething to indicate that they are enhancing the wrapped component.

  3. Key Purposes of HOC
    i) Code Reusability -
    HOCs allow you to reuse the same logic (like loading states) across different components without repeating code.
    ii) Composability -
    You can easily compose different behaviors (authentication, loading, etc.) by wrapping components with multiple HOCs.
    iii) Separation of Concerns -
    The component logic (rendering user data) is separated from the concern of showing a loading state.

  4. Basic Structure of an HOC
    i) Functional component - A simple component that displays user data.

     const UserProfile = (props) => {
       return (
         <div>
           <h1>{props.user.name}</h1>
           <p>Email: {props.user.email}</p>
         </div>
       );
     };
    

    ii) Higher-Order Component: A function that adds loading logic.

     const withLoading = (WrappedComponent) => {
       return (props) => {
         const { isLoading, ...otherProps } = props;
    
         if (isLoading) {
           return <p>Loading...</p>;
         }
    
         return <WrappedComponent {...otherProps} />;
       };
     };
    

    iii) Using the HOC - Now, we can wrap UserProfile with withLoading to create a new enhanced component.

     const UserProfileWithLoading = withLoading(UserProfile);
    
     // Usage
     function App() {
       const user = { name: "John Doe", email: "john@example.com" };
       const [isLoading, setIsLoading] = React.useState(true);
    
       // Simulate data fetching
       React.useEffect(() => {
         setTimeout(() => {
           setIsLoading(false);
         }, 2000);
       }, []);
    
       return (
         <div>
           <UserProfileWithLoading isLoading={isLoading} user={user} />
         </div>
       );
     }
    

    iv) Explaination
    a) UserProfile is a functional component that displays a user's name and email.
    b) withLoading is an HOC function that wraps the UserProfile component (or any other component).
    c) It checks the isLoading prop and, based on its value, either renders a loading message or the wrapped component.
    d) UserProfileWithLoading is the result of applying the withLoading HOC to UserProfile.
    v) Breakdown
    a) withLoading HOC - This is the higher-order function that returns a new functional component.
    b) It takes WrappedComponent (like UserProfile) as an argument. Inside the returned component, it checks the isLoading prop.
    c) If true, it returns a loading message; if false, it renders WrappedComponent with the rest of the props (...otherProps).
    d) UserProfile - This is a simple component that is enhanced by the HOC.
    e) App Component - This is where the enhanced component is used. A useState hook is used to simulate loading for 2 seconds before rendering the UserProfile.