feat(frontend): use transition for showing new data

This commit is contained in:
Julian Tölle 2022-06-25 17:41:14 +02:00
parent 4758338e99
commit 0c4de5d56a

View file

@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState, useTransition } from "react";
type UseAsync = <T>( type UseAsync = <T>(
asyncFunction: () => Promise<T>, asyncFunction: () => Promise<T>,
@ -17,19 +17,23 @@ export const useAsync: UseAsync = <T extends any>(
const [pending, setPending] = useState(false); const [pending, setPending] = useState(false);
const [value, setValue] = useState<T>(initialValue); const [value, setValue] = useState<T>(initialValue);
const [error, setError] = useState(null); const [error, setError] = useState(null);
const [, startTransition] = useTransition();
// The execute function wraps asyncFunction and // The execute function wraps asyncFunction and
// handles setting state for pending, value, and error. // handles setting state for pending, value, and error.
// useCallback ensures the below useEffect is not called // useCallback ensures the below useEffect is not called
// on every render, but only if asyncFunction changes. // on every render, but only if asyncFunction changes.
const execute = useCallback(() => { const execute = useCallback(() => {
setPending(true); startTransition(() => {
setValue(initialValue); setPending(true);
setError(null); setValue(initialValue);
setError(null);
});
return asyncFunction() return asyncFunction()
.then((response) => setValue(response)) .then((response) => startTransition(() => setValue(response)))
.catch((err) => setError(err)) .catch((err) => startTransition(() => setError(err)))
.finally(() => setPending(false)); .finally(() => startTransition(() => setPending(false)));
}, [asyncFunction, initialValue]); }, [asyncFunction, initialValue]);
// Call execute if we want to fire it right away. // Call execute if we want to fire it right away.