Open namnm opened 4 years ago
you can also pass a lifespan for the promise cache using usePromise(promiseFn, [], 1000)
, would that be enough? or do you want to selectively remove things from the cache?
@jhsu Yes I think we should have it to allow selectively/programmatically remove an item
Need to document the cache as well, it's not obvious that it's memoized. And the deepEquals technique won't always work, there should be a optional function to check equality
you can also pass a lifespan for the promise cache using usePromise(promiseFn, [], 1000), would that be enough?
For me, setting the lifespan is good enough.
As I'm using a utility library, the library should conveniently do things for me. Why do I have to do things for the library? Having to do that is a sign that the library is not good enough.
Need to document the cache as well
Anyway, in case we have to invasively remove cache from outside, I think we can design the library like this:
usePromise
.usePromise.ts:
export interface Cache {
... methods to control the cache
}
export class DefaultCache implements Cache {
... default implementation
}
export type Options = {
cache?: Cache
lifespan?: number
}
export default function usePromise<T>(
promise: (...inputs: any[]) => Promise<T>,
inputs: any[],
options: Options = {}
): T {
...
}
userCode.ts:
const cacheThatIControl = new MyCache() // or new DefaultCache() if I'm a lazy little totalitarian
usePromise(..., {cache: cacheThatIControl})
// Yay, f* you usePromise, I have total control of my cache
cacheThatIControl.controlMethod1()
cacheThatIControl.controlMethod2()
@jhsu @ngocdaothanh @vigzmv I am facing the same problem. For example: https://codesandbox.io/s/react-promise-suspense-example-forked-8nx8t?file=/src/index.js
const DelayedComponent = () => {
const [counter, setCounter] = useState(0);
const wait = usePromise(waitt, [5000], 1000);
return (
<div>
<p>I'm here</p>
<button
onClick={() => {
setCounter((c) => c + 1);
}}
>
Increment couter: {counter}
</button>
</div>
);
};
Any time we change the counter then the fallback loading will appear. That's not what we want to do. So we need a way to remove the cache manually. Like that:
const DelayedComponent = () => {
const [counter, setCounter] = useState(0);
const [wait, {remove}] = usePromise(waitt, [5000]); // <== Lifespan = 0 to cache
useEfffect(() => {
return () => {
// Remove cache on unmount.
remove();
}
}, [])
return (
<div>
<p>I'm here</p>
<button
onClick={() => {
setCounter((c) => c + 1);
}}
>
Increment couter: {counter}
</button>
</div>
);
};
I've republished as use-react-suspense and changed a little bit to provide a way to remove the cache. And better for strongly typed.
FYI The folks over at Poimandres seem to have forked this lib for @react-three/fiber
's purposes and implemented this feature along with a few others: https://github.com/pmndrs/use-asset#hooks-and-global-cache
You can use my fork of this package react-use-await.
I solved most of package issues and also provided isolated and limited caching – hope this will help you
Can we export a function to programmatically remove a cache item? The exported function should take two parameters
promiseFn
andinputs
then we can filter the cache array to remove it.