1.0.8 • Published 4 months ago

api-ui-wrapper v1.0.8

Weekly downloads
-
License
ISC
Repository
-
Last release
4 months ago

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 a data 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 a data 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?

  1. Versatility:
    Supports both client-side and server-side data fetching.

  2. Code Simplification:
    Eliminates repetitive useEffect and useState patterns for client-side fetching and getServerSideProps boilerplate for server-side.

  3. Consistency:
    Standardizes loading and error handling across multiple components.

  4. 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! 🚀

1.0.8

4 months ago

1.0.7

4 months ago

1.0.6

4 months ago

1.0.5

4 months ago

1.0.4

4 months ago

1.0.3

4 months ago

1.0.2

4 months ago

1.0.1

4 months ago

1.0.0

4 months ago