Last active
October 4, 2025 15:01
-
-
Save oriSomething/83e54e1ebf30f69bd83e4513eb8453bf to your computer and use it in GitHub Desktop.
Loading lazily services in React
This file contains hidden or 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 { use, useEffect, useState } from "react"; | |
export function createUseService<T>(loader: () => Promise<T>) { | |
let state: number = 0; | |
let listeners = new Set<(state: number) => void>(); | |
let promise: Promise<T> | undefined; | |
function listenToPromise(promise: Promise<T>) { | |
state = 1; | |
promise.then( | |
() => { | |
state = 2; | |
listeners.forEach((cb) => cb(state)); | |
}, | |
() => { | |
state = 3; | |
listeners.forEach((cb) => cb(state)); | |
} | |
); | |
} | |
function useService() { | |
if (promise === undefined) { | |
listenToPromise((promise = loader())); | |
} | |
return use(promise); | |
} | |
function useIsServiceLoaded() { | |
const [localState, setLocalState] = useState(state); | |
useEffect(() => { | |
listeners.add(setLocalState); | |
return () => listeners.delete(setLocalState); | |
}, []); | |
return localState === 2 || localState === 3; | |
} | |
function useIsServiceFailed() { | |
const [localState, setLocalState] = useState(state); | |
useEffect(() => { | |
listeners.add(setLocalState); | |
return () => listeners.delete(setLocalState); | |
}, []); | |
return localState === 3; | |
} | |
return { | |
useService, | |
useIsServiceLoaded, | |
useIsServiceFailed, | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment