A flexible and robust React hook factory for creating API hooks with consistent patterns. Build type-safe, reusable API hooks with built-in loading states, error handling, and request cancellation.
- π£ Consistent API patterns - Create uniform API hooks across your application
- π Built-in state management - Loading states, error handling, and response caching
- π― Full TypeScript support - Type-safe hooks with intelligent autocompletion
- π Request cancellation - Automatic cleanup on component unmount
- π§ Flexible configuration - Path parameters, query parameters, and custom validation
- π¦ Lightweight - Minimal dependencies, built on Axios
- π¨ Callback support - onSuccess and onError callbacks for custom handling
- β‘ Modern React - Built for React 16.8+ with hooks
npm install react-api-forge
yarn add react-api-forge
pnpm add react-api-forge
npm install @Xarlizard/react-api-forge
Note: For GitHub Packages, you'll need to configure your
.npmrc
file. See PUBLISHING.md for details.
import { createApiHook } from "react-api-forge";
// Create a typed API hook
const useGetUser = createApiHook({
method: "GET",
baseURL: "https://api.example.com",
endpoint: "/users/:userId",
requiredProps: ["userId"],
defaultProps: {
lang: "en_US",
},
pathParams: ["userId"],
queryParams: ["lang"],
});
// Use in your component
const UserProfile = ({ userId }) => {
const { response, error, loading, fetchData } = useGetUser();
useEffect(() => {
fetchData({ userId, lang: "es_ES" });
}, [userId]);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return <div>Hello, {response?.name}!</div>;
};
// Actual API call:
// https://api.example.com/users/:userId?lang=es_ES
Creates a custom API hook with the specified configuration.
Property | Type | Required | Description |
---|---|---|---|
method |
Method |
β | HTTP method (GET, POST, PUT, DELETE, etc.) |
baseURL |
string |
β | Base URL for the API endpoint |
endpoint |
string | function |
β | Endpoint path or function that returns path |
requiredProps |
array |
β | Array of required property names |
defaultProps |
object |
β | Default values for properties |
pathParams |
array |
β | Array of path parameter names (for :param replacement) |
queryParams |
array |
β | Array of query parameter names |
headers |
object |
β | Custom headers for requests |
validateResponse |
function |
β | Function to validate response data |
transformResponse |
function |
β | Function to transform response data |
onError |
function |
β | Global error handler function |
functionName |
'fetchData' | 'postData' |
β | Name of the function returned by hook |
The generated hook returns an object with:
Property | Type | Description |
---|---|---|
response |
T | null |
The response data from the API call |
error |
any | null |
Error information if the request failed |
loading |
boolean |
Loading state indicator |
fetchData |
function |
Function to trigger the API call (for GET requests) |
postData |
function |
Function to trigger the API call (for POST requests) |
const useGetPost = createApiHook({
method: "GET",
baseURL: "https://jsonplaceholder.typicode.com",
endpoint: "/posts/:postId",
requiredProps: ["postId"],
pathParams: ["postId"],
});
// Usage
const { response, loading, error, fetchData } = useGetPost();
useEffect(() => {
fetchData({ postId: "1" });
}, []);
const useCreateUser = createApiHook({
method: "POST",
baseURL: "https://api.example.com",
endpoint: "/users",
requiredProps: ["name", "email"],
functionName: "postData", // Returns postData instead of fetchData
});
// Usage
const { loading, error, postData } = useCreateUser();
const handleSubmit = (userData) => {
postData(userData, {
onSuccess: (newUser) => {
console.log("User created:", newUser);
router.push(`/users/${newUser.id}`);
},
onError: (error) => {
console.error("Failed to create user:", error);
setFormError(error.message);
},
});
};
const useSearchUsers = createApiHook({
method: "GET",
baseURL: "https://api.example.com",
endpoint: ({ category }) =>
category ? `/users/search/${category}` : "/users/search",
defaultProps: {
limit: 10,
offset: 0,
},
queryParams: ["query", "limit", "offset"],
});
// Usage
const { response, fetchData } = useSearchUsers();
useEffect(() => {
fetchData({
category: "developers",
query: "React",
limit: 20,
});
}, []);
const useGetUserProfile = createApiHook({
method: "GET",
baseURL: "https://api.example.com",
endpoint: "/users/:userId/profile",
pathParams: ["userId"],
transformResponse: (data) => ({
...data,
fullName: `${data.firstName} ${data.lastName}`,
avatar: data.avatarUrl || "/default-avatar.png",
}),
validateResponse: (data) => data && typeof data.firstName === "string",
});
const useApiCall = createApiHook({
method: "GET",
baseURL: "https://api.example.com",
endpoint: "/data",
onError: (error) => {
// Global error handling
if (error.response?.status === 401) {
// Redirect to login
window.location.href = "/login";
}
return error.response?.data?.message || "An error occurred";
},
});
const useAuthenticatedRequest = createApiHook({
method: "GET",
baseURL: "https://api.example.com",
endpoint: "/protected-data",
headers: {
Authorization: `Bearer ${getAuthToken()}`,
"Content-Type": "application/json",
},
});
const useGetData = createApiHook({
method: "GET",
baseURL: "https://api.example.com",
endpoint: ({ userId, isAdmin }) =>
isAdmin ? `/admin/users/${userId}` : `/users/${userId}`,
requiredProps: ["userId"],
pathParams: ["userId"],
});
React API Forge is built with TypeScript and provides full type safety:
interface User {
id: number;
name: string;
email: string;
}
interface GetUserProps {
userId: string;
includeProfile?: boolean;
}
const useGetUser = createApiHook<GetUserProps, User>({
method: "GET",
baseURL: "https://api.example.com",
endpoint: "/users/:userId",
requiredProps: ["userId"],
pathParams: ["userId"],
queryParams: ["includeProfile"],
});
// TypeScript will enforce correct prop types
const { response } = useGetUser();
// response is typed as User | null
- React 16.8.0 or higher
- Axios 0.21.0 or higher
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Axios for HTTP requests
- Inspired by modern React patterns and hooks
- TypeScript support for better developer experience
Made with β€οΈ by Xarlizard