@@ -17,22 +17,15 @@ interface UseListOptions {
1717export function useList ( { initialItems, onChange } : UseListOptions ) {
1818 const [ items , setItems ] = useState < ListItem [ ] > ( initialItems ) ;
1919
20+ // track updates to initialItems
2021 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+ } ) ;
2627 } , [ initialItems ] ) ;
2728
28- const updateItems = useCallback (
29- ( newItems : ListItem [ ] ) => {
30- setItems ( newItems ) ;
31- onChange ?.( newItems ) ;
32- } ,
33- [ onChange ] ,
34- ) ;
35-
3629 const itemsMap = useMemo ( ( ) => {
3730 const map = new Map < Key , ListItem > ( ) ;
3831 for ( const item of items ) {
@@ -45,46 +38,59 @@ export function useList({ initialItems, onChange }: UseListOptions) {
4538
4639 const remove = useCallback (
4740 ( 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+ } ) ;
4947 } ,
50- [ items , updateItems ] ,
48+ [ onChange ] ,
5149 ) ;
5250
5351 const moveBefore = useCallback (
5452 ( 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 ;
5760
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 ) ;
6165
62- const reordered = [ ...items ] ;
63- const [ movedItem ] = reordered . splice ( indexFrom , 1 ) ;
64- reordered . splice ( indexTo , 0 , movedItem ) ;
65- updateItems ( reordered ) ;
66+ return reordered ;
67+ } ) ;
6668 } ,
67- [ items , updateItems ] ,
69+ [ onChange ] ,
6870 ) ;
6971
7072 const moveAfter = useCallback (
7173 ( 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 ;
7477
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 ;
7881
79- const reordered = [ ...items ] ;
80- const [ movedItem ] = reordered . splice ( indexFrom , 1 ) ;
82+ const reordered = [ ...prevItems ] ;
83+ const [ movedItem ] = reordered . splice ( indexFrom , 1 ) ;
8184
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+ } ) ;
8692 } ,
87- [ items , updateItems ] ,
93+ [ onChange ] ,
8894 ) ;
8995
9096 return {
0 commit comments