The Design Philosophy Behind Daxus
This article is also included in https://github.com/jason89521/daxus#design-philosophy
Using Redux has its advantages, especially when it comes to customizing data structures. In our company, pagination is one of the most frequently used data structures for various entities like posts, comments, and forums. To simplify the process of creating paginations, our senior engineer developed a createPaginationAdapter
function.
The state type returned by createPaginationAdapter
is defined as follows:
export interface Pagination {
noMore: boolean;
index: EntityId[];
loading: boolean;
fetched: boolean;
error?: any;
}
export interface PaginationState<T> {
data: Record<EntityId, T | undefined>;
paginations: Record<string, Pagination | undefined>;
}
PaginationState
consists of two properties: data
and paginations
. data
stores all the entity data, while paginations
keeps track of the pagination states and the associated IDs.
To illustrate, let's consider the example of managing posts. When retrieving the list of posts without any filters, the API endpoint would look like /api/posts?filter=all
, and the corresponding pagination key would be filter=all
. Suppose the API returns the first page of posts with IDs 1 to 5. In this case, paginations["filter=all"]
would contain the following:
{
noMore: false,
index: [1, 2, 3, 4, 5],
loading: false,
fetched: true
}
The data
object would store the actual post data:
{
1: {
// post data
},
// and so on
}
To access the pagination for filter=all
, we can use the object obtained from createPaginationAdapter
:
const postAdapter = createPaginationAdapter();
function usePost() {
const postPagination = useSelector(state =>
postAdapter.selectByPagination(state.post, 'filter=all')
);
return postPagination;
}
At this point, you might think, "Isn't this similar to RTK's createEntityAdapter
?" Indeed, there are similarities between the two, but createPaginationAdapter
is an enhanced version specifically designed for pagination data. Now, let's delve into its most significant advantage.
Do you remember when React Query fails to meet our needs? Yes, it's when we have multiple paginations that might include the same post. React Query cannot handle this scenario effectively, but the pagination adapter perfectly solves this problem. By centralizing all the data in data
and using paginations
to collect the associated IDs, any updates to a specific post will automatically reflect in all the paginations containing that post. There won't be any inconsistencies.
So, what is the design philosophy behind Daxus?
The answer lies in customized data structures.
Every application has unique requirements for data structures. In our company, we designed PaginationState
to fulfill our needs. Daxus's design philosophy empowers developers to define and use data structures tailored to their specific requirements. You only need to invest effort in creating suitable adapters and instructing Daxus on how to fetch data and synchronize it with your model. Daxus takes care of the rest, including deduplication, revalidation, and more.
However, creating an adapter does require some code, so Daxus also strives to provide pre-built adapters that cater to most use cases. If you have any new data structures in mind that Daxus doesn't support yet, we welcome your suggestions, and we'll make an effort to implement them.
Currently, Daxus only offers
createPaginationAdapter
, and I haven't thought of other forms of data structures. If you have any ideas, please let me know!
You can give Daxus a try and provide me with any feedback. Thank you!
The repo of Daxus: https://github.com/jason89521/react-server-model
Top comments (0)