Skip to content

Commit 043e325

Browse files
committed
docs: improve docs on async data loaders
1 parent ea456a8 commit 043e325

File tree

1 file changed

+58
-21
lines changed

1 file changed

+58
-21
lines changed

packages/docs/docs/2-features/03-async-dataloader.mdx

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,41 @@ rootItemId: "root",
3838
You still hook the tree up to your data source with `dataLoader`, but can now use asynchronous methods for
3939
retrieving your tree data.
4040

41+
## Fetching all children data at once
42+
43+
The dataloader also specifies an alternative interface for fetching the payload for all children of an item
44+
at once, in case it is more convenient to you that way. This can help to reduce the number of requests of your
45+
app when a folder is opened by a user.
46+
47+
```ts
48+
const dataLoader = {
49+
getItem: (itemId) => {
50+
return wait(800).then(() => itemPayload);
51+
},
52+
getChildrenWithData: (itemId) => {
53+
return wait(800).then(() => [
54+
{ id: `child-1`, data: child1Payload },
55+
{ id: `child-2`, data: child2Payload },
56+
{ id: `child-3`, data: child3Payload },
57+
]);
58+
},
59+
};
60+
```
61+
62+
<DemoBox tags={["feature/async-data-loader"]} initialStory="react-async-async-get-children-with-data--async-get-children-with-data" />
63+
4164
## Loading Items
4265

4366
The Async Data Loader provides functionality for marking items as "loading" and displaying them as such. While item
4467
data is loading through the `getItem` function, it is considered "loading" and is intended to be displayed as such.
4568
The same goes for an items children, while their IDs are being fetched through the `getChildren` function.
4669

47-
The Async Data Loader defines a state for loading items: `state.loadingItems` keeps an array of item IDs which are currently
48-
loading. For a given item, you can check if it is loading by calling `item.isLoading()`.
49-
<!-- TODO update to new async data loader api -->
70+
The Async Data Loader defines state properties for loading items:
71+
72+
- `state.loadingItems` keeps an array of item IDs which are currently loading (via `getItem` or `getChildrenWithData`)
73+
- `state.loadingItemChildren` keeps an array of item IDs whose children are currently loading (via `getChildren` or `getChildrenWithData`)
74+
75+
For a given item, you can check if it is loading its item data or children by calling `item.isLoading()`.
5076

5177
When an item is loading, its item data will be set to the value returned by `config.createLoadingItemData`. This
5278
way, you can customize how loading items are displayed.
@@ -59,31 +85,42 @@ certain items are provided on the item instance:
5985

6086
```ts
6187
item.invalidateItemData();
62-
6388
item.invalidateChildrenIds();
6489
```
6590

6691
The data loader will then refetch the respective data the next render.
6792

68-
## Fetching all children data at once
93+
## Optimistic Item Data Invalidation
6994

70-
The dataloader also specifies an alternative interface for fetching the payload for all children of an item
71-
at once, in case it is more convenient to you that way. This can help to reduce the number of requests of your
72-
app when a folder is opened by a user.
95+
Both `item.invalidateItemData()` and `item.invalidateChildrenIds()` also accept a boolean parameter `optimistic`. If set
96+
to true, the respective data property will be refetched using the data loader implementation, but the state properties
97+
`loadingItems` and `loadingItemChildrens` will not be updated, meaning that the tree will not rerender and no items will
98+
change into a loading state, and instead continue displaying the old data. Once fetching completes, the new data will be applied
99+
into the cache and the tree will rerender with the new data.
73100

74101
```ts
75-
const dataLoader = {
76-
getItem: (itemId) => {
77-
return wait(800).then(() => itemPayload);
78-
},
79-
getChildrenWithData: (itemId) => {
80-
return wait(800).then(() => [
81-
{ id: `child-1`, data: child1Payload },
82-
{ id: `child-2`, data: child2Payload },
83-
{ id: `child-3`, data: child3Payload },
84-
]);
85-
},
86-
};
102+
item.invalidateItemData(true);
103+
item.invalidateChildrenIds(true);
104+
```
105+
106+
## Optimistic Cache Updates
107+
108+
Instead of invalidating and triggering a refetch, the cached item data can also be updated directly. This will not trigger
109+
state updates to the state properties `loadingItems` and `loadingItemChildrens`, and the tree will rerender with the new data immediately.
110+
111+
```ts
112+
item.updateCachedData({ newData: "abc" });
113+
item.updateCachedChildrenIds(["child-1", "child-2", "child-3"]);
87114
```
88115

89-
<DemoBox tags={["feature/async-data-loader"]} initialStory="react-async-async-get-children-with-data--async-get-children-with-data" />
116+
## Loading unmounted items
117+
118+
Headless Tree automatically schedules loading of items that are visibly mounted in the tree, i.e. items that are inside folders that are
119+
currently expanded. If you need to retrieve information about items that are not currently mounted, you can use the `tree.loadItemData(itemId)`
120+
or `tree.loadChildrenIds(itemId)` methods to trigger loading of specific items or their children. The methods will directly return
121+
a promise that resolves with the retrieved information, and the information will be inserted into the HT cache from where it can be used
122+
via methods like `item.getItemData()`, `item.getChildren()` or `item.getItemName()`.
123+
124+
Note that `item.getItemMeta()` will only return information about items that are visibly mounted in the tree, even if the data was forcefully
125+
loaded via `tree.loadItemData(itemId)` or `tree.loadChildrenIds(itemId)`, since that method returns information that relies on the position
126+
of the item in the tree, which is not known for unmounted items.

0 commit comments

Comments
 (0)