api-ui-wrapper v1.0.8
api-ui-wrapper
A versatile Higher-Order Component (HOC) for React that simplifies both client-side and server-side data fetching. api-ui-wrapper
supports URL-based fetching and custom fetch functions for client-side and Server-Side Rendering (SSR) in Next.js, managing loading states, error handling, and data injection into wrapped components seamlessly.
📦 Installation
To install the package, run:
npm install api-ui-wrapper
or with Yarn:
yarn add api-ui-wrapper
🚀 Usage
1. Client-Side Fetching with withClientFetching
Create a component that accepts a data
prop:
// components/Students.tsx
type Student = {
id: number;
name: string;
};
const Students = ({ data }: { data: Student[] }) => (
<ul>
{data.map((student) => (
<li key={student.id}>{student.name}</li>
))}
</ul>
);
export default Students;
Wrap the component using withClientFetching
with a custom fetch function:
// pages/index.tsx
"use client";
import { withClientFetching } from "api-ui-wrapper";
import Students from "@/components/Students";
class Data {
async fetchData(endpoint: string) {
const response = await fetch(`/api/${endpoint}`);
if (!response.ok) throw new Error("Failed to fetch data");
return response.json();
}
}
const dataManager = new Data();
const StudentData = withClientFetching(Students, () => dataManager.fetchData("students"));
const HomePage = () => (
<div>
<h1>Student List</h1>
<StudentData />
</div>
);
export default HomePage;
2. Server-Side Fetching with withServerFetching
(Next.js Only)
This feature is only available in Next.js to support Server-Side Rendering (SSR).
// pages/ssr.tsx
import { withServerFetching } from "api-ui-wrapper";
import Students from "@/components/Students";
const StudentData = withServerFetching(Students, "https://jsonplaceholder.typicode.com/users");
const SSRPage = StudentData.Component;
export const getServerSideProps = StudentData.getServerSideProps;
export default SSRPage;
Explanation:
withServerFetching
:- Accepts a component and a fetch source (URL or async function).
- Returns a wrapped component for SSR and a
getServerSideProps
function.
- Simplifies SSR data fetching by injecting data directly.
3. Fetching Data Directly with a URL (Client-Side)
If you don't need a custom fetch function, you can pass a URL string directly:
// pages/index.tsx
"use client";
import { withClientFetching } from "api-ui-wrapper";
import Dummy from "@/components/Dummy";
const DummyData = withClientFetching(Dummy, "https://jsonplaceholder.typicode.com/todos/1");
const HomePage = () => (
<div>
<h1>Dummy Data</h1>
<DummyData />
</div>
);
export default HomePage;
4. Combining Client-Side and Server-Side Fetching
// pages/index.tsx
"use client";
import { withClientFetching, withServerFetching } from "api-ui-wrapper";
import Students from "@/components/Students";
import Teachers from "@/components/Teachers";
import Dummy from "@/components/Dummy";
// Client-Side Fetching
const DummyData = withClientFetching(Dummy, "https://jsonplaceholder.typicode.com/todos/1");
// Server-Side Fetching (Next.js only)
const StudentData = withServerFetching(Students, "https://jsonplaceholder.typicode.com/users");
const SSRPage = StudentData.Component;
export const getServerSideProps = StudentData.getServerSideProps;
const HomePage = () => (
<div>
<h1>Data Management</h1>
<DummyData />
<SSRPage />
</div>
);
export default HomePage;
🛠 API Reference
withClientFetching(Component, fetchSource)
Component
(React.ComponentType<{ data: any[] }>
):
The React component to wrap. It must accept adata
prop.fetchSource
(string | () => Promise<any>
):- If a string: Treated as a URL for direct fetching.
- If a function: Expected to return a Promise resolving to an array.
Returns:
A wrapped component that handles fetching, loading, and error states.
withServerFetching(Component, fetchSource)
(Next.js Only)
Component
(React.ComponentType<{ data: any[] }>
):
The React component to wrap. It must accept adata
prop.fetchSource
(string | () => Promise<any>
):- If a string: Treated as a URL for server-side fetching.
- If a function: Expected to return a Promise resolving to an array.
Returns:
Component
: A wrapped component for SSR.getServerSideProps
: Fetches data on the server.
🟢 Why Use api-ui-wrapper
?
Versatility:
Supports both client-side and server-side data fetching.Code Simplification:
Eliminates repetitiveuseEffect
anduseState
patterns for client-side fetching andgetServerSideProps
boilerplate for server-side.Consistency:
Standardizes loading and error handling across multiple components.Type Safety:
Written in TypeScript for type-safe component wrapping.
🔄 Old Style vs. New Style
⛔ Old Style: Repetitive Code
import { useEffect, useState } from "react";
const StudentList = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
const response = await fetch("/api/students");
const result = await response.json();
setData(result);
setLoading(false);
};
fetchData();
}, []);
if (loading) return <p>Loading...</p>;
return <ul>{data.map((student) => <li key={student.id}>{student.name}</li>)}</ul>;
};
✅ New Style: Clean & Concise
import { withClientFetching } from "api-ui-wrapper";
import Students from "@/components/Students";
const StudentData = withClientFetching(Students, "/api/students");
🔄 What It Replaces
useEffect
+useState
patterns for client-side data fetching.getServerSideProps
boilerplate for SSR in Next.js.- Repetitive loading and error handling logic.
🔍 Related Patterns
- Custom Hooks: Similar to
useFetch
hooks but with enhanced flexibility. - Render Props: Offers a cleaner and more streamlined syntax.
❓ FAQ
Q: Can I use this with TypeScript?
A: Yes! api-ui-wrapper
is written in TypeScript and offers full type safety.
Q: Does it support SSR?
A: Yes, but only with withServerFetching
in Next.js.
Q: How are errors handled?
A: Errors are logged to the console. Customize error handling as needed.
🛠 Built With
- React
- TypeScript
📄 License
This package is MIT licensed. See the LICENSE file for details.
Happy coding with api-ui-wrapper
! 🚀