diff --git a/src/index.ts b/src/index.ts index ae33956..0924240 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo } from 'react'; +import { useCallback, useEffect, useMemo, useRef } from 'react'; import { type Options as MutativeOptions, type Patches, @@ -80,6 +80,7 @@ export const useTravel = ( initialState: S, { maxHistory = 10, initialPatches, ...options }: Options = {} ) => { + const resetRef = useRef(false); const [position, setPosition] = useMutative(-1); const [allPatches, setAllPatches] = useMutative( () => @@ -94,6 +95,10 @@ export const useTravel = ( }); useEffect(() => { if (position === -1 && patches.length > 0) { + if (resetRef.current) { + resetRef.current = false; + return; + } setAllPatches((_allPatches) => { _allPatches.patches.push(patches); _allPatches.inversePatches.push(inversePatches); @@ -134,18 +139,21 @@ export const useTravel = ( ) ); }; + let cachedHistory: (F extends true + ? Immutable> + : InitialValue)[]; return { position: cachedPosition, getHistory: () => { - const history = [state]; + if (cachedHistory) return cachedHistory; + cachedHistory = [state]; let currentState = state as any; for (let i = cachedPosition; i < allPatches.patches.length; i++) { currentState = apply( currentState as object, allPatches.patches[i] ) as S; - console.log('i', i, JSON.stringify(currentState)); - history.push(currentState); + cachedHistory.push(currentState); } currentState = state as any; for (let i = cachedPosition - 1; i > -1; i--) { @@ -153,11 +161,9 @@ export const useTravel = ( currentState as object, allPatches.inversePatches[i] ) as S; - console.log('j', i, JSON.stringify(currentState)); - history.unshift(currentState); + cachedHistory.unshift(currentState); } - console.log('history', JSON.stringify(history)); - return history; + return cachedHistory; }, patches: allPatches, back: (amount = 1) => { @@ -172,6 +178,7 @@ export const useTravel = ( () => initialPatches ?? { patches: [], inversePatches: [] } ); setState(() => initialState); + resetRef.current = true; }, go, canBack: () => cachedPosition > 0, diff --git a/test/index.test.ts b/test/index.test.ts index 49bf050..2a83d0b 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -8,6 +8,8 @@ describe('useTravel', () => { ); let [nextState, setState, controls] = result.current; expect(nextState).toEqual({ todos: [] }); + expect(controls.getHistory()).toEqual([{ todos: [] }]); + act(() => setState((draft) => { draft.todos.push({ @@ -29,6 +31,19 @@ describe('useTravel', () => { }, ], }); + expect(controls.getHistory()).toEqual([ + { todos: [] }, + { + todos: [ + { + name: 'todo 1', + }, + { + name: 'todo 2', + }, + ], + }, + ]); act(() => setState((draft) => { @@ -251,6 +266,7 @@ describe('useTravel', () => { act(() => controls.reset()); [nextState, setState, controls] = result.current; expect(nextState).toEqual({ todos: [] }); + expect(controls.getHistory()).toEqual([{ todos: [] }]); }); it('[useTravel] with normal init state', () => {