Create a Higher-Order Component

3 minintermediatereactcodinghigherordercomponent

Quick Answer

Build a HOC that adds loading and error states to any component that fetches data.

Detailed Answer

Create a Higher-Order Component

Build a HOC that adds loading and error states to any component that fetches data.

Solution:

interface WithDataFetchingProps {
  loading: boolean;
  error: Error | null;
  data: any;
}

function withDataFetching<P extends object>(
  WrappedComponent: React.ComponentType<P & WithDataFetchingProps>,
  fetchData: () => Promise<any>
) {
  return function WithDataFetchingComponent(props: P) {
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<Error | null>(null);
    const [data, setData] = useState(null);
    
    useEffect(() => {
      fetchData()
        .then(setData)
        .catch(setError)
        .finally(() => setLoading(false));
    }, []);
    
    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;
    
    return <WrappedComponent {...props} loading={loading} error={error} data={data} />;
  };
}

// Usage
const UserProfile = ({ data, loading, error }: { data: any } & WithDataFetchingProps) => (
  <div>{data?.name}</div>
);

const UserProfileWithData = withDataFetching(
  UserProfile,
  () => fetch('/api/user').then(res => res.json())
);