[TypeScript] redux-toolkit๊ณผ redux-thunk ๊ฐ™์ด ์‚ฌ์šฉํ•˜๊ธฐ
728x90

Today, What I learned?

ํŒ€์› ๋ถ„์˜ SOS๋กœ!.. ๋ฆฌ๋•์Šค๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๋˜ API ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋กœ์ง์„ redux-toolkit๊ณผ redux-thunk๋กœ ๋ฆฌํŒฉํ† ๋ง ํ•˜๋Š” ๊ณผ์ •์„ ๊ฐ™์ด ๊ณ ๋ฏผํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ณ ๋ฏผ์˜ ์‹œ๊ฐ„์ด ๊ธธ์—ˆ๋˜ ์ด์œ ๋Š” ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋กœ ๊ตฌ์„ฑ๋œ ํ”„๋กœ์ ํŠธ์˜€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค!..

 

 

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ createAsyncThunk

API๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ณผ์ •์—์„œ, ํ•„์š”ํ•œ ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 3๊ฐœ๋‚˜ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข€ ๋” ์–ด๋ ค์› ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.
์•„๋ž˜๋Š” ์™„์„ฑ๋œ ๋กœ์ง์ด๋‹ค. payload์— ํ•ด๋‹นํ•˜๋Š” ๋ถ€๋ถ„์„ ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น์œผ๋กœ ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

export const getSearchVideos = createAsyncThunk(
  'getSearchVideos',
  async ({ channelId, orderType, results }: VideoPayload, thunkAPI) => {
    try {
      const { data } = await request('/search', {
        params: {
          part: 'snippet',
          channelId: channelId,
          order: orderType ?? 'date',
          maxResults: results ?? 50,
          pageToken: '',
          type: 'video',
        },
      });

      return thunkAPI.fulfillWithValue(data);
    } catch (error) {
      return thunkAPI.rejectWithValue(error);
    }
  },
);

payload์˜ ํƒ€์ž…์ด ์—†์„ ๊ฒฝ์šฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ ‡๊ฒŒ ํƒ€์ž…์„ ๋”ฐ๋กœ ์ง€์ •ํ•ด ์ฃผ์—ˆ๋‹ค. ์ฑ„๋„ ์•„์ด๋””๋ฅผ ๋นผ๊ณ ๋Š” ์„ ํƒ์ ์ด๋‹ค.

interface VideoPayload {
  channelId: string;
  orderType?: string;
  results?: number;
}

 

 

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ extraReducers

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ extraReducers์— ์ •์˜ํ•ด ์ฃผ๋Š” ๋ฐฉ์‹์€ ์กฐ๊ธˆ ๋‹ฌ๋ž๋‹ค.
builder๋ผ๋Š” ๊ฒƒ์„ ์ด์šฉํ•ด์•ผ ํ•œ๋‹ค!.. 

๋ฆฌ๋•์Šค ํˆดํ‚ท ๊ณต์‹ ๋ฌธ์„œ์—๋„ ์ด๋ ‡๊ฒŒ ์ •์˜ํ•˜๋ผ๊ณ  ์•Œ๋ ค์ฃผ๊ณ  ์žˆ๊ณ ,

์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์—์„œ๋„.. builder๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•จ์„ ์•Œ๋ ค์ฃผ๊ณ  ์žˆ๋‹ค. ๋‚ฏ์„ค์ง€๋งŒ ์‚ฌ์šฉํ•ด๋ณผ ์ˆ˜ ๋ฐ–์—...

์ฐธ๊ณ ๋กœ ๋ฆฌ๋•์Šค ํˆดํ‚ท์˜ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ ์šฉ ๊ด€๋ จ ๊ณต์‹๋ฌธ์„œ ํ•ญ๋ชฉ์€ ์•„๋ž˜ ์ฃผ์†Œ!..

https://redux-toolkit.js.org/usage/usage-with-typescript

 

 

๊ทธ๋ž˜์„œ ์™„์„ฑ๋œ ์ฝ”๋“œ๋Š” ์ด๋ ‡๋‹ค.

const mediaSlice = createSlice({
  name: 'media',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(getSearchVideos.fulfilled, (state, { payload }) => {
      state.search = payload.items;
      state.nextPageToken = payload.nextPageToken;
    });
  },
});

ํˆดํ‚ท์œผ๋กœ ๋ฆฌํŒฉํ† ๋ง ํ–ˆ์œผ๋‹ˆ useSelector์™€ useDispatch๋„ ๋”ฐ๋กœ ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

์œ„์—์„œ payload์˜ ํƒ€์ž… ์ค‘์— ์„ ํƒ์ ์œผ๋กœ ๋“ค์–ด๊ฐ€๋Š” ๊ฐ’์„ ์ •ํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜,

 useEffect(() => {
    dispatch(getSearchVideos({ channelId }));
  }, [dispatch]);

 

 

์ด๋Ÿฐ ์‹์œผ๋กœ payload ๊ฐ’์„ ์ฃผ์–ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

useEffect(() => {
    const payload = {
      channelId: item.snippet.channelId,
      orderType: 'viewCount',
      results: 15,
    };

    dispatch(getSearchVideos(payload));
  }, []);

 

 

 

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋งˆ๋ƒฅ ์ต์ˆ™ํ•˜์ง€ ์•Š๋‹ค ๋ณด๋‹ˆ payload์˜ ํƒ€์ž…์„ ์–ด๋–ป๊ฒŒ ์ค„ ๊ฒƒ์ธ์ง€ ์‚ฝ์งˆ์„ ๋งŽ์ด ํ–ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค!..
ํ”„๋กœ์ ํŠธ ์ค‘์ธ๋ฐ ๋” ๋งŽ์€ ์‹œ๊ฐ„์„ ์Ÿ์•„๋ถ“์ง€ ์•Š์€ ๊ฒƒ์ด ๋‹คํ–‰์ด๋‹ค. ๐Ÿ˜‡

 

 

 

์ฐธ๊ณ ๊ธ€

 

How to use createAsyncThunk with Typescript? How to set types for the `pending` and `rejected` payloads?

Right now I've got these actions that I use for an upload thunk's lifecycle. type UPLOAD_START = PayloadAction<void> type UPLOAD_SUCCESS = PayloadAction<{ src: string, sizeKb: number }&g...

stackoverflow.com

 

 

 

Redux Toolkit์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒํƒœ ๊ด€๋ฆฌํ•˜๊ธฐ,reselect, redux, react, immer, redux-action, FSA, react-redux ์‚ฌ

Redux Toolkit์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒํƒœ ๊ด€๋ฆฌํ•˜๊ธฐ, reselect, redux, react, immer, redux-action, FSA, react-redux ์‚ฌ์šฉ๋ฒ•, redux, react, react16, state management, flux, store, reducer, dispatch, action

kyounghwan01.github.io

 

728x90