Last active
February 15, 2024 12:38
-
-
Save sagarpanchal/8dfa9ef65da0378efe710a3dc71bc3f9 to your computer and use it in GitHub Desktop.
Zustand Usage Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createStore } from "zustand" | |
import { subscribeWithSelector } from "zustand/middleware" | |
export function chain<T>(object: T) { | |
const call = | |
<V>(previousResult: V) => | |
<U>(callback: (object: T, result: V) => U) => { | |
const result = callback(object, previousResult) | |
return { call: call(result), result: () => result, object: () => object } | |
} | |
return { call: call(undefined), result: () => undefined, object: () => object } | |
} | |
export class LoaderService { | |
static readonly store = createStore(subscribeWithSelector(() => 0)) | |
private static subscriptions: (() => void)[] = [] | |
static set count(n: number) { | |
LoaderService.store.setState(n) | |
} | |
static get count() { | |
return LoaderService.store.getState() | |
} | |
static get isLoading() { | |
return LoaderService.store.getState() > 0 | |
} | |
static startLoading() { | |
this.count = chain(this.count) | |
.call((count) => (count < 1 ? 1 : count)) | |
.result() | |
} | |
static stopLoading() { | |
this.count = chain(this.count) | |
.call((count) => (count < 0 ? 0 : count)) | |
.result() | |
} | |
static adjustCount(count: number) { | |
LoaderService.store.setState(LoaderService.store.getState() + count) | |
} | |
public static init() { | |
LoaderService.dispose() | |
LoaderService.subscriptions = [ | |
LoaderService.store.subscribe( | |
(count) => count, | |
(count, prevCount) => { | |
if (count < 0) LoaderService.store.setState(0) | |
switch (true) { | |
case count > prevCount: | |
console.info("Loading started") | |
break | |
case count < prevCount: | |
console.info("Loading stopped") | |
break | |
} | |
}, | |
), | |
] | |
} | |
public static dispose() { | |
LoaderService.subscriptions.forEach((unsubscribe) => unsubscribe()) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createStore, useStore } from "zustand"; | |
import { subscribeWithSelector } from "zustand/middleware"; | |
// store | |
export const store = createStore( | |
subscribeWithSelector(() => ({ | |
loading: 0, | |
})) | |
); | |
// action to start loading | |
export const startLoading = () => { | |
store.setState({ loading: store.getState().loading + 1 }); | |
}; | |
// action to stop loading | |
export const stopLoading = () => { | |
store.setState({ loading: store.getState().loading - 1 }); | |
}; | |
// usage with react function component | |
export const ReactComponent = () => { | |
const isLoading = useStore((state) => state.loading > 0); | |
return <div>{isLoading}</div>; | |
}; | |
// Subscription with selectors | |
const removeSubscription = store.subscribe( | |
(state) => state.loading, | |
(loading, prevLoading) => { | |
switch (true) { | |
case loading > prevLoading: { | |
console.log("loading started"); | |
break; | |
} | |
case loading < prevLoading: { | |
console.log("loading stopped"); | |
break; | |
} | |
} | |
}, | |
{ fireImmediately: true } | |
); | |
// to stop listening to changes | |
removeSubscription(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment