The code above defines an entity adapter that will allow us to retrieve users by their id, name, or username. The adapter also has a selector to filter by the user's id. The adapter also exports selectors to get all users, select a specific user by id, select id's, select entities, and select the total number of users.
import { createSlice, createEntityAdapter } from "@reduxjs/toolkit";
import { friendbookApi } from "../../services/friendbookApi";
const usersAdapter = createEntityAdapter({
selectId: (user) => user.id,
sortComparer: (a, b) => a.name.localeCompare(b.name),
});
const initialState = usersAdapter.getInitialState({
selectedUser: {},
});
const usersSlice = createSlice({
name: "users",
initialState,
reducers: {
userAdded: usersAdapter.addOne,
userUpdated: usersAdapter.updateOne,
userDeleted: usersAdapter.removeOne,
},
});
const usersApi = friendbookApi.injectEndpoints({
endpoints: (build) => ({
getUsers: build.query({
query: () => "/users",
transformResponse: (response) => {
return usersAdapter.setAll(initialState, response);
},
transformErrorResponse: (response) => response.error,
providesTags: ["Users"],
}),
getUser: build.query({
query: (id) => `/users/${id}`,
transformResponse: (response) => response.user,
transformErrorResponse: (response) => response.error,
providesTags: (result, error, id) => [
{ type: "User", id },
...(!result ? [] : [{ type: "User", id: result.id }]),
],
}),
}),
});
export const { userAdded, userUpdated, userDeleted } = usersSlice.actions;
export const {
selectAll: selectAllUsers,
selectById: selectUserById,
selectIds: selectUserIds,
selectEntities: selectUserEntities,
selectTotal: selectTotalUsers,
} = usersAdapter.getSelectors((state) => state.users);
export const { useGetUsersQuery, useGetUserQuery } = usersApi;
export default usersSlice.reducer;