RTK / RTK Query Basic

createAction๋‘ ๊ฐ€์ง€ ์ธ์ˆ˜๋ฅผ ์ทจํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” ์ž‘์—… ์œ ํ˜•์ด๋ฉฐ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์†Œ์œ„ prepare๋กœ, ๊ฒฐ๊ณผ ์ž‘์—… ์ƒ์„ฑ์ž๋กœ๋ถ€ํ„ฐ ์ธ์ˆ˜๋ฅผ ์ˆ˜๋ฝํ•˜๊ณ  ์ด๋Ÿฌํ•œ ์ธ์ˆ˜๋ฅผ ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ๋กœ ์ž‘์—… ๊ฐœ์ฒด์— ์ฒจ๋ถ€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ค€๋น„ ๊ธฐ๋Šฅ์€ ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค .

createAction takes two arguments. The first one is the action type and it's required. The second argument is a so-called prepare function which wecan use to accept arguments from the resulting action creator and attach these arguments as additional data to the action object. The prepare function is optional.

Redux Toolkitโ€Š-โ€ŠA Simple Example Workflow


extraReducers allows createSlice to respond to other action types besides the types it has generated.

extraReducers๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด createSlice๊ฐ€ ์ƒ์„ฑํ•œ ์ž‘์—… ์œ ํ˜• ์ด์™ธ์˜ ๋‹ค๋ฅธ ์ž‘์—… ์œ ํ˜•์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

As case reducers specified with extraReducers are meant to reference "external" actions, they will not have actions generated in slice.actions.

As with reducers , these case reducers will also be passed to createReducer and may "mutate" their state safely.

The recommended way of using extraReducers is to use a callback that receives a ActionReducerMapBuilder instance.


unwrap()

we can await addNewPost().unwrap() to handle any potential errors with a standard try/catch block.


RTK Query

export const postsApi = createApi({
  reducerPath: "posts",
  baseQuery: fetchBaseQuery({
    baseUrl: '/api',
    prepareHeaders: (headers) => { // ๋น„๋™๊ธฐ ๋กœ์ง๋„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      ...
      return headers;
    },
  })
  tagTypes: ["Post List"],  // ์บ์‹ฑ์— ์‚ฌ์šฉ๋  ํƒœ๊ทธ์˜ ํƒ€์ž…
  endpoints: (build) => ({
    getPosts: build.query({  // HTTP GET์˜ ๊ฒฝ์šฐ
      query: () => ({ url: "posts" }),
      provideTags: [{ type: "Post List" }],  // ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ์— ํƒœ๊ทธ ๋ถ€์—ฌ
    }),
    postPost: build.mutation({  // POST, PATCH, DELETE ๋“ฑ์˜ ๊ฒฝ์šฐ
      query: (body) => {
        return {
          url: "/posts",
          method: "POST",
          body,
        };
      },
      invalidateTags: [{ type: "Post List" }],  // ํ•ด๋‹น ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง„ ์บ์‹œ ๋ฐ์ดํ„ฐ ์ œ๊ฑฐ(ํƒ€์ž… ์ฒดํฌ๋„ ์ž๋™์œผ๋กœ ๋จ)
    }),
  }),
});

invalidatesTags๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๊ฐ€ ๋˜๋ฉด ์ž๋™์œผ๋กœ ํŒจ์น˜๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

deleteTodo: builder.mutation({
      query: (id: number) => ({
        url: `/todo/${id}`,
        method: 'DELETE',
      }),
      invalidatesTags: ['Todos'],
    }),

Get all todos

query: () => endpoint

providesTags๋Š” invalidatesTags๊ฐ€ ์‹คํ–‰๋  ๋•Œ ์ž๋™์œผ๋กœ ํŒจ์น˜๋  ์ฟผ๋ฆฌ

getAllTodos: builder.query<TodoModel[], String>({
      query: () => '/allTodos',
      providesTags: ['Todos'],
    }),

Last updated