mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: rewrite preview to use React.Suspense
This commit is contained in:
parent
22fde9d808
commit
cd021716f1
3 changed files with 179 additions and 97 deletions
63
src/hooks/useSuspendable.ts
Normal file
63
src/hooks/useSuspendable.ts
Normal file
|
@ -0,0 +1,63 @@
|
|||
import { useReducer, useCallback, useRef } from "react";
|
||||
|
||||
type Status = "idle" | "pending" | "resolved" | "rejected";
|
||||
|
||||
type Action<T> =
|
||||
| { type: "start" }
|
||||
| { type: "resolve"; payload: T }
|
||||
| { type: "reject"; payload: Error };
|
||||
|
||||
type State<T> = {
|
||||
status: Status;
|
||||
result: T | null;
|
||||
error: Error | null;
|
||||
};
|
||||
|
||||
function reducer<T>(state: State<T>, action: Action<T>): State<T> {
|
||||
switch (action.type) {
|
||||
case "start":
|
||||
return { ...state, status: "pending" };
|
||||
case "resolve":
|
||||
return { status: "resolved", result: action.payload, error: null };
|
||||
case "reject":
|
||||
return { status: "rejected", result: null, error: action.payload };
|
||||
default:
|
||||
throw new Error("Unhandled action type");
|
||||
}
|
||||
}
|
||||
|
||||
export function useSuspendable<T>(): [
|
||||
T | null,
|
||||
Error | null,
|
||||
Status,
|
||||
(promise: Promise<T>) => Promise<void>,
|
||||
Promise<T> | null,
|
||||
] {
|
||||
const [state, dispatch] = useReducer(reducer, {
|
||||
status: "idle",
|
||||
result: null,
|
||||
error: null,
|
||||
});
|
||||
|
||||
const pendingPromise = useRef<Promise<T> | null>(null);
|
||||
|
||||
const suspend = useCallback((promise: Promise<T>) => {
|
||||
pendingPromise.current = promise;
|
||||
dispatch({ type: "start" });
|
||||
return promise
|
||||
.then((data) => {
|
||||
dispatch({ type: "resolve", payload: data });
|
||||
})
|
||||
.catch((error) => {
|
||||
dispatch({ type: "reject", payload: error as Error });
|
||||
});
|
||||
}, []);
|
||||
|
||||
return [
|
||||
state.result as T | null,
|
||||
state.error,
|
||||
state.status,
|
||||
suspend,
|
||||
pendingPromise.current,
|
||||
];
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue