leo-query
v0.2.0
Published
A simple library to connect async queries to Zustand stores.
Downloads
196
Readme
A simple library to connect async queries to Zustand stores.
Try a live demo here. And see full documentation here. And chat on discord here.
npm i leo-query
Getting Started Javascript
See Typescript Getting Started here.
Write your async functions
const db = {bears: 0};
export const bears = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(db.bears);
}, 1000);
});
};
export const increasePopulation = () => {
return new Promise((resolve) => {
setTimeout(() => {
db.bears = db.bears + 1;
resolve();
}, 1000);
});
};
export const removeAllBears = () => {
return new Promise((resolve) => {
setTimeout(() => {
db.bears = db.bears = 0;
resolve();
}, 1000);
});
};
Create a store
const useBearStore = create(() => ({
increasePopulation: effect(increasePopulation),
removeAllBears: effect(removeAllBears),
bears: query(bears, s => [s.increasePopulation, s.removeAllBears])
}));
Create your hook
const useBearStoreAsync = hook(useBearStore);
Bind your components
function BearCounter() {
const bears = useBearStoreAsync(state => state.bears);
return <h1>{bears} around here ...</h1>;
}
function Controls() {
const increasePopulation = useBearStore(state => state.increasePopulation.trigger);
return <button onClick={increasePopulation}>one up</button>;
}
Wrap in Suspense
function App() {
return (
<>
<Suspense fallback={<h1>Loading...</h1>}>
<BearCounter/>
</Suspense>
<Controls/>
</>
);
}
Why Leo?
Leo is the simplest and safest way to connect async queries to Zustand stores.
Why Leo over TanStack Query?
- Integrates directly into your store
- No need to write async queries in your components
Why Leo over vanilla fetch?
- Automatically caches queries
- Automatically handles dependencies
- No need to update the store in useEffects
Getting Started TypeScript
Write the same functions, just with types!
Write your async functions
const db = {bears: 0};
// Simulated async functions
export const bears = (): Promise<number> => {
return new Promise((resolve) => {
setTimeout(() => resolve(db.bears), 1000);
});
};
export const increasePopulation = (): Promise<void> => {
return new Promise((resolve) => {
setTimeout(() => {
db.bears = db.bears + 1;
resolve();
}, 1000);
});
};
export const removeAllBears = (): Promise<void> => {
return new Promise((resolve) => {
setTimeout(() => {
db.bears = db.bears = 0;
resolve();
}, 1000);
});
};
Create a store
interface BearsState {
bears: Query<BearsState, number>;
increasePopulation: Effect<BearsState, []>;
removeAllBears: Effect<BearsState, []>;
}
const useBearStore = create(() => ({
increasePopulation: effect(increasePopulation),
removeAllBears: effect(removeAllBears),
bears: query(bears, s => [s.increasePopulation, s.removeAllBears])
}));
Create your hook
const useBearStoreAsync = hook(useBearStore);
Bind your components
function BearCounter() {
const bears = useBearStoreAsync(state => state.bears);
return <h1>{bears} around here ...</h1>;
}
function Controls() {
const increasePopulation = useBearStore(state => state.increasePopulation.trigger);
return <button onClick={increasePopulation}>one up</button>;
}
Wrap in Suspense
function App() {
return (
<>
<Suspense fallback={<h1>Loading...</h1>}>
<BearCounter />
</Suspense>
<Controls />
</>
);
}
Examples
| Example | Description | |---------------------------------------------------------------------------------------------------|------------------------------------| | Bears JS | A simple bear counter (Javascript) | | Bears TS | A simple bear counter (Typescript) | | Task Manager | A more complex task manager app. |