usecreatefunc
v1.6.0
Published
this function create your hooks and store automate
Readme
🧠 usecreatefunc
A smart utility for quickly creating CRUD + State Management hooks using Redux Toolkit EntityAdapter and SWR (for caching and fetching).
🚀 Features
✅ Automatic slice creation for any entity
✅ Syncs Redux state with SWR data automatically
✅ Supports silent mode (no network fetch)
✅ Supports initialState
✅ Computed fields support via extra
✅ Full client-side CRUD with optional server sync
📦 Installation
npm install usecreatefunc
# or
yarn add usecreatefunc⚙️ Quick Usage
on ../store.ts file, create a store that support dynamic injact slices
import { createStore } from "usecreatefunc";
export const { store, injectEntitySlice, useAppDispatch, useAppSelector } =
createStore({});on .../axios.ts file, create axios and settings
import axios from "axios";
export const axiosUser = axios.create({
baseURL: `...`,
});on .../usecreatefunc.ts file, create the hook factory
import { createCreateFunc } from "usecreatefunc";
import { axiosUser } from "./axios";
import { store, injectEntitySlice } from "./store";
export const useCreateFunc = createCreateFunc({
fetcher: axiosUser,
store,
injectEntitySlice: injectEntitySlice as any,
});on .../hooks/useUser.ts file, create a hook for your entity
interface UserType {
id: number;
name: string;
email: string;
fullName: string;
}
const useUsers = useCreateFunc<UserType>({
name: "users",
endpoint: "/api/users",
initialState: [
{ id: 1, name: "Placeholder User", email: "[email protected]" },
],
extra: {
// optional computed fields
fullName: (user) => `${user.name} (${user.email})`,
},
});and when you need to use this hook:
function UsersList() {
const { data, isLoading, fetch_create, fetch_delete } = useUsers();
if (isLoading) return <p>Loading...</p>;
return (
<div>
{data.map((user) => (
<div key={user.id}>
{user.fullName}
<button onClick={() => fetch_delete(user.id)}>🗑️</button>
</div>
))}
<button
onClick={() =>
fetch_create({ name: "New User", email: "[email protected]" })
}
>
➕ Add User
</button>
</div>
);
}⚙️ Inputs
| Prop | Type | Description |
| -------------- | ---------------------------------------- | -------------------------------------------- |
| name | string | Entity name used for slice and Redux key |
| endpoint | string | API endpoint URL |
| silent | boolean | If true, SWR does not fetch from the network |
| initialState | T[] | Initial data to populate Redux on mount |
| extra | { [key: string]: (row, store) => any } | Functions to compute derived fields |
🧮 Hook Output
The returned hook provides full state and CRUD functions:
| Function / Value | Type | Description |
| -------------------- | ------------------------------------- | ---------------------------------------------- |
| data | T[] | Final list of data (including computed fields) |
| error | Error \| undefined | Fetch error if any |
| isLoading | boolean | Loading status |
| mutate | Function | SWR function to revalidate or invalidate cache |
| selectAll() | () => T[] | Get all data from Redux |
| selectById(id) | (id: EntityId) => T \| undefined | Get a single item from Redux |
| addOne(data) | (data: Omit<T, "id">) => void | Add item locally (no server sync) |
| setOne(data) | (data: T) => void | Replace one item in Redux |
| setAll(data) | (data: T[]) => void | Replace all data in Redux |
| updateOne(data) | (data: T) => void | Update one item locally |
| updateMany(data[]) | (data: T[]) => void | Update multiple items locally |
| deleteOne(id) | (id: T["id"]) => void | Delete one item locally |
| deleteMany(ids[]) | (ids: T["id"][]) => void | Delete multiple items locally |
| fetch_create(data) | (data: Omit<T, "id">) => Promise<T> | Create on server and sync to Redux |
| fetch_update(data) | (data: T) => Promise<T> | Update on server and sync to Redux |
| fetch_delete(id) | (id: T["id"]) => Promise<T["id"]> | Delete from server and sync to Redux |
💡 Notes
🔸 Silent Mode
Useful for SSR or offline scenarios:
const { data } = useUsers({ silent: true });Data will only come from Redux, no network request will be made.
🔸 Initial State
Set initial data before the first fetch:
const useUsers = useCreateFunc<User>({
name: "users",
endpoint: "/api/users",
initialState: [{ id: 1, name: "Test" }],
});🔸 Computed Fields (extra)
Create derived fields dynamically:
extra: {
fullName: (user) => `${user.name} (${user.email})`,
}🧱 High-Level Structure
createCreateFunc()
├── useCreateFunc()
│ ├── useSWR() → handles fetch & cache
│ ├── Redux Entity Slice → manages local state
│ ├── extra → computed fields
│ └── CRUD → fetch_create, fetch_update, fetch_delete
└── Returns entity-specific hook🧪 Quick Test Example
const useProducts = useCreateFunc<Product>({
name: "products",
endpoint: "/api/products",
});
function ProductList() {
const { data, fetch_create } = useProducts();
return (
<div>
{data.map((p) => (
<div key={p.id}>{p.name}</div>
))}
<button onClick={() => fetch_create({ name: "New Product" })}>
Add Product
</button>
</div>
);
}🧰 Requirements
react≥ 18@reduxjs/toolkit≥ 2.0swr≥ 2.0
🪄 License
MIT © Mahdi Nouri
