import type { Ref } from 'vue'; import { onBeforeUnmount, ref } from 'vue'; import raf from '../raf'; export type Updater = (prev: State) => State; /** * Execute code before next frame but async */ export function useLayoutState( defaultState: State, ): [Ref, (updater: Updater) => void] { const stateRef = ref(defaultState); let tempState = stateRef.value; let updateBatchRef = []; const rafRef = ref(); function setFrameState(updater: Updater) { raf.cancel(rafRef.value); updateBatchRef.push(updater); rafRef.value = raf(() => { const prevBatch = updateBatchRef; // const prevState = stateRef.value; updateBatchRef = []; prevBatch.forEach(batchUpdater => { tempState = batchUpdater(tempState); }); // if (tempState !== stateRef.value) { stateRef.value = tempState; // } }); } onBeforeUnmount(() => { raf.cancel(rafRef.value); }); return [stateRef as Ref, setFrameState]; }