File name
Commit message
Commit date
File name
Commit message
Commit date
09-14
File name
Commit message
Commit date
'use client';
import { useTransition } from 'react';
import { useFeedback } from '@/app/_hooks/use-feedback';
/**
* 화면이 기다려야 하는 동작을 전역 스피너와 함께 돌린다 — `useTransition`을 그대로 쓰되
* 진행 중 표시를 붙인 것이다.
*
* 삭제처럼 확인 얼럿이 닫힌 뒤에 진행되는 동작은 표시가 행 아이콘 하나뿐이라 눌렸는지조차
* 알기 어렵다. 그런 자리에 쓴다 — 버튼이 스스로 "저장 중"을 보여주는 자리에는 쓰지 않는다.
*
* 스피너를 켜는 것은 transition 밖에서 한다. 안에서 켜면 낮은 우선순위로 밀려 늦게 그려진다.
* 끄는 것은 안에서 해야 갱신된 화면이 준비될 때까지 스피너가 남는다.
*/
export function useBlockingAction(): [
boolean,
(action: () => void | Promise<void>) => void,
] {
const { showSpinner, hideSpinner } = useFeedback();
const [isPending, startTransition] = useTransition();
function run(action: () => void | Promise<void>) {
showSpinner();
startTransition(async () => {
try {
await action();
} finally {
hideSpinner();
}
});
}
return [isPending, run];
}