@@ -33,17 +33,30 @@ export interface TreeLoaderOptions {
3333 loadingTransitionMs ?: number ;
3434}
3535
36+ const initialRootNodes = { isLoading : true , items : [ ] } ;
37+ const initialChildren = { } ;
38+ const initialTrails = { } ;
39+
3640export function useTreeLoader < T > (
3741 source : TreeSource < T > ,
3842 state : TreeState ,
3943 options ?: TreeLoaderOptions | null ,
4044) : RootTree < T > {
4145 const { loadingTransitionMs = 0 } = options || { } ;
42- const [ rootNodes , setRootNodes ] = useState < LoadableArray < TreeSourceNode < T > > > ( { isLoading : true , items : [ ] } ) ;
43- const [ children , setChildren ] = useState < StringMap < LoadableArray < TreeSourceNode < T > > > > ( { } ) ;
44- const [ trails , setTrails ] = useState < StringMap < Array < TreeSourceNode < T > > > > ( { } ) ;
46+ const [ rootNodes , setRootNodes ] = useState < LoadableArray < TreeSourceNode < T > > > ( initialRootNodes ) ;
47+ const [ children , setChildren ] = useState < StringMap < LoadableArray < TreeSourceNode < T > > > > ( initialChildren ) ;
48+ const [ trails , setTrails ] = useState < StringMap < Array < TreeSourceNode < T > > > > ( initialTrails ) ;
4549
4650 const statefulNodes = useRef < StringMap < TreeNode < T > > > ( { } ) ;
51+ const sourceRef = useRef ( source ) ;
52+
53+ // If the source changes, reset all data and start again.
54+ if ( source !== sourceRef . current ) {
55+ sourceRef . current = source ;
56+ setRootNodes ( initialRootNodes ) ;
57+ setChildren ( initialChildren ) ;
58+ setTrails ( initialTrails ) ;
59+ }
4760
4861 const { activeId, expandedIds } = state ;
4962
@@ -63,6 +76,10 @@ export function useTreeLoader<T>(
6376 // Load root nodes immediately.
6477 useEffect ( ( ) => {
6578 source . children ( null ) . then ( ( loadedRootNodes ) => {
79+ if ( source !== sourceRef . current ) {
80+ // The source has been changed.
81+ return ;
82+ }
6683 setRootNodes ( { isLoading : false , items : loadedRootNodes } ) ;
6784 addTrails ( loadedRootNodes . map ( ( child ) => [ child ] ) ) ;
6885 } ) ;
@@ -72,6 +89,10 @@ export function useTreeLoader<T>(
7289 useEffect ( ( ) => {
7390 if ( activeId && ! trails [ activeId ] ) {
7491 source . trail ( activeId ) . then ( ( loadedTrail ) => {
92+ if ( source !== sourceRef . current ) {
93+ // The source has been changed.
94+ return ;
95+ }
7596 addTrails ( suffixes ( loadedTrail ) ) ;
7697 } ) ;
7798 }
@@ -110,13 +131,18 @@ export function useTreeLoader<T>(
110131 clearTimeout ( loadingTransitionTimeout as any ) ;
111132 }
112133
134+ if ( source !== sourceRef . current ) {
135+ // The source has been changed.
136+ return ;
137+ }
138+
113139 // Add the children to state.
114140 const loadedChildren : StringMap < LoadableArray < TreeSourceNode < T > > > = Object . fromEntries ( results ) ;
115141 setChildren ( ( currentChildren ) => ( { ...currentChildren , ...loadedChildren } ) ) ;
116142
117143 // Add trails for the new children so we can make them active.
118144 addTrails ( Object . entries ( loadedChildren ) . flatMap (
119- ( [ id , childrenForId ] ) => childrenForId . items . map ( ( child ) => [ child , ...trails [ id ] ] ) ,
145+ ( [ id , childrenForId ] ) => trails [ id ] ? childrenForId . items . map ( ( child ) => [ child , ...trails [ id ] ] ) : [ ] ,
120146 ) ) ;
121147 } ) ;
122148 } , [ expandedIds , children , trails , activeTrailIds , source , addTrails , setChildren , loadingTransitionMs ] ) ;
0 commit comments