-
Notifications
You must be signed in to change notification settings - Fork 778
/
apiSlice.js
71 lines (69 loc) · 2.16 KB
/
apiSlice.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
export const apiSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: '/fakeApi' }),
tagTypes: ['Post'],
endpoints: (builder) => ({
getPosts: builder.query({
query: () => '/posts',
providesTags: (result = [], error, arg) => [
'Post',
...result.map(({ id }) => ({ type: 'Post', id })),
],
}),
getPost: builder.query({
query: (postId) => `/posts/${postId}`,
providesTags: (result, error, arg) => [{ type: 'Post', id: arg }],
}),
addNewPost: builder.mutation({
query: (initialPost) => ({
url: '/posts',
method: 'POST',
body: initialPost,
}),
invalidatesTags: ['Post'],
}),
editPost: builder.mutation({
query: (post) => ({
url: `posts/${post.id}`,
method: 'PATCH',
body: post,
}),
invalidatesTags: (result, error, arg) => [{ type: 'Post', id: arg.id }],
}),
addReaction: builder.mutation({
query: ({ postId, reaction }) => ({
url: `posts/${postId}/reactions`,
method: 'POST',
// In a real app, we'd probably need to base this on user ID somehow
// so that a user can't do the same reaction more than once
body: { reaction },
}),
async onQueryStarted({ postId, reaction }, { dispatch, queryFulfilled }) {
// `updateQueryData` requires the endpoint name and cache key arguments,
// so it knows which piece of cache state to update
const patchResult = dispatch(
apiSlice.util.updateQueryData('getPosts', undefined, (draft) => {
// The `draft` is Immer-wrapped and can be "mutated" like in createSlice
const post = draft.find((post) => post.id === postId)
if (post) {
post.reactions[reaction]++
}
})
)
try {
await queryFulfilled
} catch {
patchResult.undo()
}
},
}),
}),
})
export const {
useGetPostsQuery,
useGetPostQuery,
useAddNewPostMutation,
useEditPostMutation,
useAddReactionMutation,
} = apiSlice