강의

멘토링

로드맵

Inflearn brand logo image

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

i1004gy님의 프로필 이미지
i1004gy

작성한 질문수

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

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

createAsyncThunk 진행 순서

해결된 질문

작성

·

282

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

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

  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
질문자

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에 저장되는 것이 아닌가요?

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

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

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

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

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

i1004gy님의 프로필 이미지
i1004gy

작성한 질문수

질문하기