@@ -4,6 +4,8 @@ title: "Handling external state updates"
44category : recipe
55---
66
7+ import { DemoBox } from " ../../src/components/demo/demo-box" ;
8+
79Generally, Headless Tree loads the tree structure once when it is loaded, and loads subsequent substructures
810whenever parts of the visual tree change, e.g. because a folder is expanded that was collapsed before.
911Headless Tree provides ways to mutate the tree via drag events or renaming, and makes sure that it reloads
@@ -44,8 +46,18 @@ const addNode = () => {
4446 items [" item3" ] = { name: " Item 3" , children: [] };
4547 tree .rebuildTree ();
4648};
49+
50+ const removeNode = () => {
51+ delete items [" item2" ];
52+ items [" item1" ].children = items [" item1" ].children .filter (id => id !== " item2" );
53+ tree .rebuildTree ();
54+ };
4755```
4856
57+ The following sample shows how to add and delete items from a synchronous tree, as well mutating their data by renaming them.
58+
59+ <DemoBox tags = { [" guide/externaldata" ]} initialStory = { " react-guides-external-data-management-sync-data--sync-data" } />
60+
4961## Asynchronous Trees
5062
5163For asynchronous trees, the general gist of how trees are updated is the same, however the ` asyncDataLoaderFeature `
@@ -62,4 +74,35 @@ item.invalidateChildrenIds();
6274```
6375
6476You will not have to additionally call ` tree.rebuildTree() ` , as this is done automatically by the async
65- data loader feature once it has refetched the data.
77+ data loader feature once it has refetched the data.
78+
79+ Instead of invalidating and waiting for a refetch, you can also directly update the cached data of an item
80+ or its cached children ids, if you already have the new data available:
81+
82+ ``` ts
83+ const item = tree .getItemInstance (" item1" );
84+ item .updateCachedData ({ ... item .getItemData (), name: " New name" });
85+ item .updateCachedChildrenIds ([" child1" , " child2" ]);
86+ ```
87+
88+ In the demo below, you can see the same samples for adding and deleting data as above, but with
89+ an async data loader instead. In this sample, the cache is updated with ` item.updateCachedChildrenIds() `
90+ and ` item.updateCachedData() ` . Note that you do need to call ` tree.rebuildTree() ` after mutating
91+ the data this way.
92+
93+ <DemoBox tags = { [" guide/externaldata" ]} initialStory = { " react-guides-external-data-management-async-data--async-data" } />
94+
95+ ## Managing tree data in a React state
96+
97+ Most samples in the documentation use a data loader implementation that lives outside of React, since in most
98+ cases the data loader will directly interface with your backend or other external data source to provide
99+ tree data to Headless Tree.
100+
101+ The sample below demonstrates how to manage the tree data in a React state. The most relevant gotcha is that calling
102+ ` rebuildTree() ` may behave unexpectedly in cases where data is stored in a React state. If you mutate your tree data
103+ by updating the React state, the ` useState ` getter will only reflect the new state during the next rerender.
104+ Calling ` rebuildTree() ` immediately after you made your changes, will result in the rebuild logic running on the old
105+ data from before the rerender. To combat this, you can use ` tree.scheduleRebuildTree() ` instead, trigger a rebuild
106+ the next time ` tree.getItems() ` is called, which will be after the next rerender.
107+
108+ <DemoBox tags = { [" guide/externaldata" ]} initialStory = { " react-guides-external-data-management-data-in-react-state--data-in-react-state" } />
0 commit comments