@@ -9,20 +9,25 @@ import usePersistentState, {
99
1010function BasicTestComponent ( {
1111 label,
12+ useInitializerFunction = false ,
1213 type = 'test' ,
1314 version = 1 ,
1415 migrations,
1516} : {
1617 label : string ;
18+ useInitializerFunction ?: boolean ;
1719 type ?: string ;
1820 version ?: number ;
1921 migrations ?: PersistentStateMigration [ ] ;
2022} ) {
21- const [ state , setState ] = usePersistentState ( `default-${ label } ` , {
22- type,
23- version,
24- migrations,
25- } ) ;
23+ const [ state , setState ] = usePersistentState (
24+ useInitializerFunction ? ( ) => `default-${ label } ` : `default-${ label } ` ,
25+ {
26+ type,
27+ version,
28+ migrations,
29+ }
30+ ) ;
2631 return (
2732 < div >
2833 < span > { `${ state } ` } </ span >
@@ -78,6 +83,30 @@ describe('usePersistentState', () => {
7883 ] ) ;
7984 } ) ;
8085
86+ it ( 'should support function state initializer if no previous initialState' , ( ) => {
87+ const mockOnChange = jest . fn ( ) ;
88+
89+ render (
90+ < >
91+ < BasicTestComponent label = "foo" useInitializerFunction />
92+ < BasicTestComponent label = "bar" useInitializerFunction />
93+ < BasicTestComponent label = "baz" />
94+ </ > ,
95+ {
96+ wrapper : createWrapper ( { onChange : mockOnChange } ) ,
97+ }
98+ ) ;
99+
100+ expect ( screen . getByText ( 'default-foo' ) ) . toBeInTheDocument ( ) ;
101+ expect ( screen . getByText ( 'default-bar' ) ) . toBeInTheDocument ( ) ;
102+ expect ( screen . getByText ( 'default-baz' ) ) . toBeInTheDocument ( ) ;
103+ expect ( mockOnChange ) . toHaveBeenCalledWith ( [
104+ expect . objectContaining ( { state : 'default-foo' } ) ,
105+ expect . objectContaining ( { state : 'default-bar' } ) ,
106+ expect . objectContaining ( { state : 'default-baz' } ) ,
107+ ] ) ;
108+ } ) ;
109+
81110 it ( 'should update state and trigger onChange' , async ( ) => {
82111 const mockOnChange = jest . fn ( ) ;
83112
@@ -422,7 +451,27 @@ describe('usePersistentState migrations', () => {
422451 expect ( mockOnChange ) . not . toHaveBeenCalled ( ) ;
423452 } ) ;
424453
425- test ( 'should throw if the from version is greater than to' , ( ) => {
454+ test ( 'should throw if the persisted version is greater than the hook' , ( ) => {
455+ TestUtils . disableConsoleOutput ( 'error' ) ;
456+ const mockOnChange = jest . fn ( ) ;
457+ const initialState = [
458+ {
459+ type : 'test' ,
460+ version : 2 ,
461+ state : 'v2' ,
462+ } ,
463+ ] ;
464+
465+ expect ( ( ) =>
466+ render ( < BasicTestComponent label = "foo" version = { 1 } /> , {
467+ wrapper : createWrapper ( { initialState, onChange : mockOnChange } ) ,
468+ } )
469+ ) . toThrowError ( / n e w e r v e r s i o n / ) ;
470+
471+ expect ( mockOnChange ) . not . toHaveBeenCalled ( ) ;
472+ } ) ;
473+
474+ test ( 'should throw if the migration from version is greater than to' , ( ) => {
426475 TestUtils . disableConsoleOutput ( 'error' ) ;
427476 const mockOnChange = jest . fn ( ) ;
428477 const initialState = [
0 commit comments