Skip to content

Commit 8c6ef48

Browse files
committed
docs(daxus): update document
1 parent a1db8c0 commit 8c6ef48

20 files changed

Lines changed: 47 additions & 2309 deletions

README.md

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![PR's Welcome][pr-welcoming-image]][pr-welcoming-url]
66
[![Test coverage][codecov-image]][codecov-url]
77

8-
Daxus is a server state management library for building a single source of truth of state.
8+
Daxus is a server state management library for building a single source of truth.
99

1010
- Customizable data structure
1111
- This feature enable you to build a single source of truth
@@ -27,7 +27,6 @@ Daxus is a server state management library for building a single source of truth
2727
- [Mutation](#mutation)
2828
- [Pagination](#pagination)
2929
- [Invalidate Accessor](#invalidate-accessor)
30-
- [FlowChart](#flowchart)
3130
- [Documents](#documents)
3231
- [Development Motivation](#development-motivation)
3332
- [Why not use React Query?](#why-not-use-react-query)
@@ -69,11 +68,13 @@ npm install daxus
6968
## Simple Example
7069

7170
```typescript
71+
export const db = createDatabase();
7272
// You don't have to use createPaginationAdapter specifically.
7373
// You can use any data structure that meets your requirements.
7474
export const postAdapter = createPaginationAdapter<Post>();
75-
export const postModel = createModel(postAdapter.initialState);
76-
export const getPostById = postModel.defineNormalAccessor<number, Post>({
75+
export const postModel = db.createModel({ name: 'post', initialState: postAdapter.initialState });
76+
export const getPostById = postModel.defineAccessor<Post, number>({
77+
name: 'getPostById',
7778
fetchData: async arg => {
7879
const data = await getPostApi({ id: arg });
7980
return data;
@@ -98,7 +99,8 @@ export function usePost(id: number) {
9899
return { data, error, isFetching, revalidate: () => accessor.revalidate() };
99100
}
100101

101-
export const getPostList = postModel.defineInfiniteAccessor<string, Post[]>({
102+
export const getPostList = postModel.defineInfiniteAccessor<Post[], string>({
103+
name: 'getPostList',
102104
fetchData: async filter => {
103105
return getPostListApi({ filter });
104106
},
@@ -115,13 +117,20 @@ export function usePostList(filter: string) {
115117

116118
## Getting Started
117119

120+
First of all, let's create a database for daxus:
121+
122+
```ts
123+
import { createDatabase } from 'daxus';
124+
export const db = createDatabase();
125+
```
126+
118127
When using Daxus, you need to create models for different types of data. Taking our company as an example, the backend data includes posts, comments, forums, and more. You must create separate models for them when using Daxus.
119128

120129
Different models can use different data structures. For example, posts are suitable for storing data using a pagination data structure, while user settings may not be. You need to create different data structures for your models based on different requirements.
121130

122131
```typescript
123132
const postAdapter = createPaginationAdapter<Post>();
124-
const postModel = createModel(postAdapter.initialState);
133+
const postModel = db.createModel({ name: 'post', initialState: postAdapter.initialState });
125134
```
126135

127136
> The object returned by `createPaginationAdapter` provides not only the initial state but also various operation functions for handling pagination. This allows developers to manipulate pagination easily. Of course, you can design your own pagination if desired, as Daxus gives developers complete control over data.
@@ -131,7 +140,8 @@ const postModel = createModel(postAdapter.initialState);
131140
After creating the model, you can start defining accessors. Accessors play a significant role in Daxus as they help fetch data from the server and synchronize it with your model once the data is obtained. Then, after your model is updated, it notifies the components that use the corresponding model to check if rerendering is necessary.
132141

133142
```typescript
134-
const getPostById = postModel.defineNormalAccessor<number, Post>({
143+
const getPostById = postModel.defineAccessor<Post, number>({
144+
name: 'getPostById',
135145
fetchData: async id => {
136146
const data = await getPostApi(id);
137147
return data;
@@ -142,16 +152,15 @@ const getPostById = postModel.defineNormalAccessor<number, Post>({
142152
});
143153
```
144154

145-
There are two type of the accessors. One is `normal`, the other one is `infinite`. You can use `model.defineNormalAccessor` to define a normal accessor, and use `model.defineInfiniteAccessor` to define an infinite accessor. Typically, you would only use `infinite` when implementing infinite loading. In most cases, `normal` is sufficient.
155+
There are two type of the accessors. One is `normal`, the other one is `infinite`. You can use `model.defineAccessor` to define a normal accessor, and use `model.defineInfiniteAccessor` to define an infinite accessor. Typically, you would only use `infinite` when implementing infinite loading. In most cases, `normal` is sufficient.
146156

147-
The argument is the accessor's **action**. `fetchData` tells the accessor how to fetch data from the server, while `syncState` specifies how to synchronize the obtained data with the model's state.
157+
The argument is the accessor's **action**. `name` is the name of the creator, `fetchData` tells the accessor how to fetch data from the server, while `syncState` specifies how to synchronize the obtained data with the model's state.
148158

149-
`defineNormalAccessor` and `defineInfiniteAccessor` returns an accessor creator function. Next, we will use the accessor created by `defineNormalAccessor` with the `useAccessor` hook.
159+
`defineAccessor` and `defineInfiniteAccessor` returns an accessor creator function. Next, we will use the accessor created by `defineAccessor` with the `useAccessor` hook.
150160

151161
```typescript
152162
function usePost(id: number) {
153-
const accessor = getPostById(id);
154-
const { data, error, isFetching } = useAccessor(accessor, state =>
163+
const { data, error, isFetching, accessor } = useAccessor(getPostById(id), state =>
155164
postAdapter.tryReadOne(state, id)
156165
);
157166

@@ -163,8 +172,7 @@ The second argument of `useAccessor` determines the shape of the `data`. You can
163172

164173
```typescript
165174
function usePostTitle(id: number) {
166-
const accessor = getPostById(id);
167-
const { data } = useAccessor(accessor, state => postAdapter.tryReadOne(state, id)?.title);
175+
const { data } = useAccessor(getPostById(id), state => postAdapter.tryReadOne(state, id)?.title);
168176

169177
return data;
170178
}
@@ -197,7 +205,8 @@ Daxus provides the `createPaginationAdapter` to help developers easily handle pa
197205
Since pagination uses ID to reference all entities, when any entity updates, all paginations that include this entity will receive the latest data. Developers don't have to worry about inconsistent data across multiple lists.
198206

199207
```typescript
200-
const getPostList = postModel.defineInfiniteAccessor<{ layout: string }, Post[]>({
208+
const getPostList = postModel.defineInfiniteAccessor<Post[], { layout: string }>({
209+
name: 'getPostList',
201210
fetchData: async ({ layout }, { previousData }) => {
202211
if (previousData.length === 0) return null; // Reaching end.
203212
const data = await getPostListApi({ layout });
@@ -210,8 +219,7 @@ const getPostList = postModel.defineInfiniteAccessor<{ layout: string }, Post[]>
210219
});
211220

212221
function usePostList(layout: string) {
213-
const accessor = getPostList({ layout });
214-
const { data, error, isFetching } = useAccessor(accessor, state => {
222+
const { data, error, isFetching, accessor } = useAccessor(getPostList({ layout }), state => {
215223
const key = `layout=${layout}`;
216224
// A rerender will be triggered if any entity is updated
217225
// Don't worry that the user might see inconsistent results
@@ -232,26 +240,6 @@ getPostById.invalidate(); // invalidate all accessors generated by this accessor
232240
postModel.invalidate(); // invalidate all accessors related to this model
233241
```
234242

235-
## FlowChart
236-
237-
```mermaid
238-
flowchart TD
239-
subgraph createModel
240-
direction LR
241-
m(model)
242-
state[(state)]
243-
end
244-
s[(server)]
245-
NAC(normalAccessorCreator)
246-
NA(normalAccessor)
247-
m --> |defineNormalAccessor| NAC
248-
NAC --> NA
249-
NA --> |fetchData| s
250-
s --> |Data| NA
251-
NA --> |syncState| state
252-
253-
```
254-
255243
## Documents
256244

257245
- [The Difference With React Query](./docs/the-difference-with-RQ.md)

docs/accessor.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Model and Accessor
22

3-
In Daxus, you need to create different models for different types of data. For example, you can create a model for post data and another model for comment data.
3+
In Daxus, you need to create a database, then create different models for different types of data. For example, you can create a model for post data and another model for comment data.
44

55
The reason for creating different models is that different data may require different data structures. Pagination structure is suitable for post data, while it may not be as suitable for user data.
66

77
```ts
8+
const db = createDatabase();
89
const postAdapter = createPaginationAdapter<Post>();
9-
const postModel = createModel(postAdapter.initialState);
10+
const postModel = db.createModel({ name: 'post', initialState: postAdapter.initialState });
1011
```
1112

1213
Daxus provides a pagination helper function called `createPaginationAdapter`. It helps you build and easily read/write pagination structures. For more information, you can refer to the [pagination page](./pagination.md).
@@ -18,7 +19,8 @@ Daxus provides a pagination helper function called `createPaginationAdapter`. It
1819
Accessors play a crucial role in Daxus. Almost all functionality is built upon them, including deduplication, revalidation on focus, and subscribing to the state of the model.
1920

2021
```ts
21-
const getPostById = postModel.defineNormalAccessor<string, Post>({
22+
const getPostById = postModel.defineAccessor<Post, string>({
23+
name: 'getPostById',
2224
fetchData: postId => {
2325
return getPostApi({ postId });
2426
},
@@ -34,13 +36,13 @@ const getPostById = postModel.defineNormalAccessor<string, Post>({
3436
});
3537
```
3638

37-
To define an accessor, you need to provide two pieces of information to your model. The `fetchData` function specifies how to fetch the remote data, while the `syncState` function determines how to sync the fetched data to the state of the model.
39+
To define an accessor, you need to provide three pieces of information to your model. The `name` property is the name of its creator. The `fetchData` function specifies how to fetch the remote data, while the `syncState` function determines how to sync the fetched data to the state of the model.
3840

3941
Moreover, you can specify `onSuccess` and `onError` to perform some side effect when fetching success or fail.
4042

41-
`defineNormalAccessor` returns an accessor creator that you can use to create an accessor. We encourage you to name the creator based on its purpose. In the example above, the accessor fetches post based on the given ID, so it is named `getPostById`.
43+
`defineAccessor` returns an accessor creator that you can use to create an accessor. We encourage you to name the creator based on its purpose. In the example above, the accessor fetches post based on the given ID, so it is named `getPostById`.
4244

43-
> There is another method called `defineInfiniteAccessor` that is useful when implementing infinite scrolling. For more information, please refer to its [API documentation](./api/README.md#createmodel).
45+
> There is another method called `defineInfiniteAccessor` that is useful when implementing infinite scrolling.
4446
4547
### `useAccessor`
4648

@@ -63,6 +65,7 @@ When using the `useAccessor` hook, revalidation occurs in the following cases:
6365

6466
- The return value of `checkHasData` is `false`.
6567
- The accessor is stale, and `revalidateIfStale` is `true`.
68+
- The accessor is changed, and `revalidateOnMount` is `true`.
6669
- The window regains focus, and `revalidateOnFocus` is `true`.
6770
- The network is reconnected, and `revalidateOnReconnect` is `true`.
6871

0 commit comments

Comments
 (0)