@@ -17,22 +17,15 @@ interface UseListOptions {
17
17
export function useList ( { initialItems, onChange } : UseListOptions ) {
18
18
const [ items , setItems ] = useState < ListItem [ ] > ( initialItems ) ;
19
19
20
+ // track updates to initialItems
20
21
useEffect ( ( ) => {
21
- // preventing callback loop, we cannot rely on useEffect dependency since that does not utilize deep comparison
22
- if ( _ . isEqual ( initialItems , items ) ) return ;
23
-
24
- setItems ( initialItems ) ;
25
- // eslint-disable-next-line react-hooks/exhaustive-deps
22
+ setItems ( ( prevItems ) => {
23
+ // preventing callback loop
24
+ if ( _ . isEqual ( initialItems , prevItems ) ) return prevItems ;
25
+ return initialItems ;
26
+ } ) ;
26
27
} , [ initialItems ] ) ;
27
28
28
- const updateItems = useCallback (
29
- ( newItems : ListItem [ ] ) => {
30
- setItems ( newItems ) ;
31
- onChange ?.( newItems ) ;
32
- } ,
33
- [ onChange ] ,
34
- ) ;
35
-
36
29
const itemsMap = useMemo ( ( ) => {
37
30
const map = new Map < Key , ListItem > ( ) ;
38
31
for ( const item of items ) {
@@ -45,46 +38,59 @@ export function useList({ initialItems, onChange }: UseListOptions) {
45
38
46
39
const remove = useCallback (
47
40
( key : Key ) => {
48
- updateItems ( items . filter ( ( item ) => key !== item . id ) ) ;
41
+ // updateItems(items.filter((item) => key !== item.id));
42
+ setItems ( ( prevItems ) => {
43
+ const newItems = prevItems . filter ( ( item ) => key !== item . id ) ;
44
+ onChange ?.( newItems ) ;
45
+ return newItems ;
46
+ } ) ;
49
47
} ,
50
- [ items , updateItems ] ,
48
+ [ onChange ] ,
51
49
) ;
52
50
53
51
const moveBefore = useCallback (
54
52
( targetKey : Key , keys : Iterable < Key > ) => {
55
- const key = Array . from ( keys ) [ 0 ] ;
56
- if ( key === targetKey ) return ;
53
+ setItems ( ( prevItems ) => {
54
+ const key = Array . from ( keys ) [ 0 ] ;
55
+ if ( key === targetKey ) return prevItems ;
56
+
57
+ const indexFrom = prevItems . findIndex ( ( item ) => item . id === key ) ;
58
+ const indexTo = prevItems . findIndex ( ( item ) => item . id === targetKey ) ;
59
+ if ( indexFrom === - 1 || indexTo === - 1 ) return prevItems ;
57
60
58
- const indexFrom = items . findIndex ( ( item ) => item . id === key ) ;
59
- const indexTo = items . findIndex ( ( item ) => item . id === targetKey ) ;
60
- if ( indexFrom === - 1 || indexTo === - 1 ) return ;
61
+ const reordered = [ ...prevItems ] ;
62
+ const [ movedItem ] = reordered . splice ( indexFrom , 1 ) ;
63
+ reordered . splice ( indexTo , 0 , movedItem ) ;
64
+ onChange ?.( reordered ) ;
61
65
62
- const reordered = [ ...items ] ;
63
- const [ movedItem ] = reordered . splice ( indexFrom , 1 ) ;
64
- reordered . splice ( indexTo , 0 , movedItem ) ;
65
- updateItems ( reordered ) ;
66
+ return reordered ;
67
+ } ) ;
66
68
} ,
67
- [ items , updateItems ] ,
69
+ [ onChange ] ,
68
70
) ;
69
71
70
72
const moveAfter = useCallback (
71
73
( targetKey : Key , keys : Iterable < Key > ) => {
72
- const key = Array . from ( keys ) [ 0 ] ;
73
- if ( key === targetKey ) return ;
74
+ setItems ( ( prevItems ) => {
75
+ const key = Array . from ( keys ) [ 0 ] ;
76
+ if ( key === targetKey ) return prevItems ;
74
77
75
- const indexFrom = items . findIndex ( ( item ) => item . id === key ) ;
76
- const indexTo = items . findIndex ( ( item ) => item . id === targetKey ) ;
77
- if ( indexFrom === - 1 || indexTo === - 1 ) return ;
78
+ const indexFrom = prevItems . findIndex ( ( item ) => item . id === key ) ;
79
+ const indexTo = prevItems . findIndex ( ( item ) => item . id === targetKey ) ;
80
+ if ( indexFrom === - 1 || indexTo === - 1 ) return prevItems ;
78
81
79
- const reordered = [ ...items ] ;
80
- const [ movedItem ] = reordered . splice ( indexFrom , 1 ) ;
82
+ const reordered = [ ...prevItems ] ;
83
+ const [ movedItem ] = reordered . splice ( indexFrom , 1 ) ;
81
84
82
- // Adjust if removing item before target index
83
- const insertIndex = indexFrom < indexTo ? indexTo : indexTo + 1 ;
84
- reordered . splice ( insertIndex , 0 , movedItem ) ;
85
- updateItems ( reordered ) ;
85
+ // Adjust if removing item before target index
86
+ const insertIndex = indexFrom < indexTo ? indexTo : indexTo + 1 ;
87
+ reordered . splice ( insertIndex , 0 , movedItem ) ;
88
+ onChange ?.( reordered ) ;
89
+
90
+ return reordered ;
91
+ } ) ;
86
92
} ,
87
- [ items , updateItems ] ,
93
+ [ onChange ] ,
88
94
) ;
89
95
90
96
return {
0 commit comments