Higher Order Component
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,
higherOrderComponentis a function that takes a component (WrappedComponent) and returns a new component (EnhancedComponent).const EnhancedComponent = higherOrderComponent(WrappedComponent);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
withSomethingorenhanceSomethingto indicate that they are enhancing the wrapped component.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.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
UserProfilewithwithLoadingto 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)UserProfileis a functional component that displays a user's name and email.
b)withLoadingis an HOC function that wraps theUserProfilecomponent (or any other component).
c) It checks theisLoadingprop and, based on its value, either renders a loading message or the wrapped component.
d)UserProfileWithLoadingis the result of applying thewithLoadingHOC toUserProfile.
v) Breakdown
a)withLoadingHOC - This is the higher-order function that returns a new functional component.
b) It takesWrappedComponent(likeUserProfile) as an argument. Inside the returned component, it checks theisLoadingprop.
c) If true, it returns a loading message; if false, it rendersWrappedComponentwith the rest of the props (...otherProps).
d)UserProfile- This is a simple component that is enhanced by the HOC.
e)AppComponent - This is where the enhanced component is used. AuseStatehook is used to simulate loading for 2 seconds before rendering theUserProfile.