usePromiseResolve
使い方
jsfunction App() {
const [getPromise, resolve] = usePromiseResolve()
useEffect(()=>{
(async () => {
const event = await getPromise()
console.log(event)
})()
},[])
return <div onMouseDown={resolve}>hoge</div>
}
getPromiseが関数呼び出しなのに注意
実行するたびに新たにpromiseを作る
resoveする方は同一の関数を使い回せる
ソース
tsimport { useRef, useCallback } from "react";
function useRefFn<Fn extends CallableFunction>() {
const ref = useRef<Fn>();
const fn = useCallback((...args) => {
ref.current?.(...args);
}, []);
return [fn, (fn: Fn) => (ref.current = fn)] as const;
}
type Resolve<T> = (value: T) => void;
function makePromise<T>(
setRes: (resolve: Resolve<T>) => void,
cancel?: Promise<void>
): Promise<T> {
return new Promise((res, rej) => {
setRes(res);
cancel?.then(() => rej());
});
}
export function usePromiseResolve<T>() {
const [resolve, setResolve] = useRefFn<(arg: T) => void>();
const getPromise = () => makePromise(setResolve);
return [getPromise, resolve] as const;
}
useRefFnというhooksを用意している
これは、呼び出す関数自体はuseCallbackでシングルトンな存在
シングルトンというのは、レンダリングを通して同一という意味
useRefで関数を保持して、こいつを呼び出す
とにかくレンダリングと独立して1つの関数を保持したいときに使える
getPromiseで新しいpromiseを作るようにしてるのは、繰り返しpromiseを待つのに必要だから
そうでないと一度resolveしたらそれで終わりになる
todo
cancelとかのapiも入れたい