인프런 커뮤니티 질문&답변

i1004gy님의 프로필 이미지

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

인피니트 스크롤링 적용하기

createAsyncThunk 진행 순서

해결된 질문

23.07.04 16:57 작성

·

250

0

제가 이번에 loadPosts를 createAsyncThunk로 구현하면서 createAsyncThunk의 진행 순서가 궁금해서 질문 드립니

index.js
 
 useEffect(() => {
    console.log("dipathch hi");
    dispatch(loadPosts(10));
  }, [dispatch]);
reducers/post.js
export const loadPosts = createAsyncThunk(LOAD_POST, async (data) => {
  trottle();
  return data;
});
const trottle = () =>
  listenerMiddleware.startListening({
    type: LOAD_POST,
    effect: async (action, listenerApi) => {
      listenerApi.unsubscribe();
      console.log("Original state ", listenerApi.getOriginalState());
      await listenerApi.delay(5000);
      console.log("Current state ", listenerApi.getState());
      listenerApi.subscribe();
    },
  });
const postSlice = createSlice({
  name: "post",
  initialState,

  extraReducers: (builder) =>
    builder
      .addCase([HYDRATE], (state, action) => ({
        ...state,
        ...action.payload.post,
      }))
      // loadPosts
      .addCase(loadPosts.pending, (state, action) => {
        state.loadPostsLoading = true;
        state.loadPostsDone = false;
      })
      .addCase(loadPosts.fulfilled, (state, action) => {
        action.payload = generateDummpyPost(action.payload);
        state.mainPosts = action.payload.concat(state.mainPosts);
        state.hasMorePost = state.mainPosts.length < 50;
        state.loadPostsLoading = false;
        state.loadPostsDone = true;
      })
      .addCase(loadPosts.rejected, (state, action) => {
        state.loadPostsLoading = false;
        state.loadPostsError = action.error;
      })
      .addDefaultCase((state) => state),
});

제가 하나하나 console.log를 찍어서 확인한 진행 순서를 얘기해 드리겠습니다

일단 화면을 처음 랜더링할때 index.js에서 dispatch가 제일 먼저 실행됩니다 그리고 post.js로 넘어와서 loadPost.pending -> loadPosts.fulfilled ->loadPosts = createAsyncThunk(LOAD_POST) 이 순서대로 진행이 됩니다 그래서 loadPosts.fulfilled에 generateDummpyPost()함수를 작성한 것입니다

그래서 마지막에 createAsyncThunk가 실행이 되니 return이 필요없지 않나? 라는 생각에 return을 지워봤더니 post가 하나만 작성되고 그 이후는 작성되지 않았습니다

제가 궁금한 부분은 세개입니다

  1. createAsyncThunk의 정확한 진행순서가 궁금합니다

  2. generateDummpyPost()함수를 저렇게 작성하는게 맞는지 궁금합니다

  3. https://blog.logrocket.com/redux-toolkits-new-listener-middleware-vs-redux-saga/ 에서 Throttling관련 얘기가 있어서 똑같이 따라 해봤는데 쓰로틀링을 createAsyncThunk에 장착하는 방법을 잘 모르겠습니다 쓰로틀링이 없어도 윈도우 이밴트로 요청이 한번에 많이 오는 현상은 없지만 그래도 궁금해서 질문 드립니다

 

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2023. 07. 04. 17:02

  1. createAsyncThunk(LOAD_POST) -> pending -> createAsyncThunk의 return값에 따라 fulfilled 순서대로 진행됩니다. dispatch(loadPosts(10))를 했으니 당연히 createAsyncThunk가 먼저 실행되죠. loadPosts가 createAsyncThunk잖아요. 그 후 pending이 dispatch되고, createAsyncThunk의 body 부분이 실행되고 여기서 throw를 하면 rejected, return을 하면 fulfilled가 실행되는 것입니다.

  2. generateDummyPost를 안 보여주셨습니다. 제 코드 그대로 쓰신 거라면 그냥 일반적인 함수라서 일반적인 함수처럼 돌아갑니다.

  3. 저도 redux toolkit의 throttling 방식을 아직 안 해봐서 모릅니다.

i1004gy님의 프로필 이미지
i1004gy
질문자

2023. 07. 07. 13:59

export const loadPosts = createAsyncThunk(LOAD_POST, async (data) => {
  console.log(data);
  const Dummy = generateDummpyPost(data);
  console.log(Dummy);
  // trottle();
  return Dummy;
});

createAsyncThunk의 return을 Dummy로 바꿔서 보내도

.addCase(loadPosts.fulfilled, (state, action) => {
  console.log(action);
  action.payload = action.payload;
  state.mainPosts = action.payload.concat(state.mainPosts);
  state.hasMorePost = state.mainPosts.length < 50;
  state.loadPostsLoading = false;
  state.loadPostsDone = true;
})

console.log와 redux dev tools 모두에서 return을 보낸 Dummy의 행방을 찾을 수 없습니다

action.payload에는 post data하나만이 보일 뿐입니다

createAsyncThunk에서 보낸 return이 action.payload에 저장되는 것이 아닌가요?

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2023. 07. 07. 14:00

action.payload에 post data 하나만 보인다고 하셨는데, 그게 Dummy입니다.

i1004gy님의 프로필 이미지
i1004gy
질문자

2023. 07. 11. 15:31

제가 올린 코드로 했을 때 payload에 데이터가 10개가 들어가있어야 하는데 1개만 들어가 있어서 질문드린거였는데 지금 또 다시해보니까 10개가 제대로 들어가 있네요...

일단 계속 하다가 또 문제가 생기면 다시 질문 드리겠습니다 감사합니다!!!

i1004gy님의 프로필 이미지

작성한 질문수

질문하기