프론트엔드 개발/React

리덕스 툴킷) createAsyncThunk 로 비동기 처리하기

Ella Seon 2023. 3. 31. 10:34

0. 개요

🔸리덕스 툴킷을 사용하면 전역 상태관리를 쉽게 관리할 수 있다. 즉, 여러 컴포넌트에서 공유되는 걸 전역 상태로 관리하면 좋다. 

🔸어떤 데이터를 전역상태로 관리하면 좋을까? 구체적인 예시는?

-  서버로 부터 가져온 데이터 : 서버로부터 가져온 데이터를 전역 상태에 저장해서 여러 컴포넌트에서 공유하는 것이 좋다.  전역에서 자주 사용되는 api를 호출하거나, api 호출한 결과를 여러군데에서 사용해야할 상황이 생기기 때문

✅ 왜 서버로부터 가져온 데이터를 전역에서 관리하는게 좋을까?

1) 데이터 공유: 전역 상태를 사용하면 여러 컴포넌트에서 동일한 데이터에 접근할 수 있다. 이는 데이터를 중복으로 가져오지 않고, 여러 컴포넌트 간에 일관된 데이터를 사용할 수 있도록 한다. 예를 들어, 여러 개의 컴포넌트에서 사용하는 사용자 정보나 애플리케이션의 설정과 같은 데이터를 전역 상태로 저장하면 컴포넌트 간에 데이터를 손쉽게 공유할 수 있다.
2) 상태 유지: 전역 상태는 애플리케이션의 상태를 유지할 수 있다. 서버로부터 데이터를 한 번 가져온 후에는 이를 전역 상태에 저장하여 다른 컴포넌트에서 다시 가져오지 않아도 된다. 이는 성능을 향상시키고, 네트워크 요청을 줄여줌으로써 애플리케이션의 응답성을 개선할 수 있습니다.
3) 상태의 일관성: 전역 상태를 사용하면 상태를 일관성 있게 유지할 수 있다. 여러 컴포넌트가 동일한 상태를 공유하고 업데이트할 때, 전역 상태를 사용하면 상태의 일관성을 유지하기 쉽다. Redux Toolkit을 사용하면 상태 업데이트 로직을 단순화하고, 예측 가능하고 일관된 방식으로 상태를 변경할 수 있다.

 

10/2 업데이트) => 현재는 서버상태를 전역상태로 관리하는 것보다는 React-Query 와 같은 걸로 서버상태를 관리하는게 더 좋다는 생각을 해서 리팩토링을 하였음

 

 

리덕스 툴킷에서 제공하는 유틸리티 함수 중 하나로, 비동기 작업을 처리하는 createAsycThunk 사용해보자!

 

생활코딩의 영상을 보며 대략적인 개념을 알아보자

https://www.youtube.com/watch?v=K-3sBc2pUJ4&t=407s

 

전체코드

https://stackblitz.com/edit/react-adv...

1. createAsyncThunk

🔸전체적인 흐름

1) createAsyncThunk 에 비동기 통신 함수를 담는다.

2) createSlice 에 액션타입에 따라 어떤 상태로 변화할지 적는다. 

3) createSlice에서 상태를 적용하고 싶은 곳에 useSelector 를 사용한다.

 

🔶createAsyncThunck

 

1) createAsyncThunk 의 인자

- thunk의 이름 (slice의 name 과 createAsyncThunk를 담는 변수명을 주로 적는다 ex: counterSlice/asyncUpFetch)

- 작업이 완료되었을 때 처리해야 하는 액션을 생성하는 콜백함수

 

비동기 작업이 성공적으로 완료되면 콜백 함수가 실행되고, promise 결과를 반환한다. 반환하는 곳은 reducer의 slice 함수에 반환을 하게 된다. 

 

2) extraReducers

 

- extraReducers는 Redux Toolkit에서 제공하는 기능 중 하나로, createSlice 함수로 생성된 reducer에 추가적인 리듀서 로직을 쉽게 추가할 수 있게 해준다.

- builder 함수는 체이닝 방식을 사용한다.

아래 예제에서 보면, builder 함수는 'accCase'메서드를 호출하여 asyncUpFetch.pending 과 asyncUpFetch.fulfilled, asyncUpFetch.rejected 액션 타입에 대한 리듀서 로직을 작성한다. 

- addCase 메서드는 두 개의 인자를 받으며, 첫 번째 인자는 액션 타입을 나타내는 문자열 또는 action creator 함수이고, 두 번째 인자는 해당 액션에 대한 리듀서 로직을 처리하는 함수입니다.


➕ 프로젝트에 적용해보기

- 아래 그림과 같이 회원가입 창 안에  아이디를 입력하고 중복확인 버튼을 누르면 결과값을 바로 밑에 알려주는 

비동기 통신을 하려고 한다. 

 

// 아이디 유효성 검증
export const fetchIdValidate = createAsyncThunk(
  "join/fetchIdValidate",
  async (id: string, { rejectWithValue }) => {
    try {
      const response = await axios.post(
        `${BASE_URL}/accounts/signup/valid/username/`,
        { username: id }
      );
      // console.log(response.data);
      return response.data;
    } catch (error) {
      const axiosError = error as AxiosError;
      console.error("Error in fetchIdValidate:", axiosError.response?.data);
      return rejectWithValue(axiosError.response?.data);
    }
  }
);

fetchIdValidate 함수는 createAsyncThunk 함수를 사용하여 비동기 작업을 처리하는 함수이다. 이 함수는 두 개의 파라미터를 받는다. 첫 번째 파라미터는 액션 타입(prefix)을 지정하는 문자열이며, 두 번째 파라미터는 비동기 작업을 처리하는 함수이다. 이 함수에서는 두 개의 파라미터를 받습니다.
첫 번째 파라미터는 액션에서 사용할 payload를 의미한다. 위 예제에서는 id가 이에 해당한다. 두 번째 파라미터는 { rejectWithValue }와 같이 객체 형태로 전달되며, 비동기 작업에서 rejectWithValue 메서드를 사용할 수 있도록 해준다. 

따라서 id: string은 첫 번째 파라미터로 전달되는 값이며, 액션에서 사용할 payload이다. { rejectWithValue }는 두 번째 파라미터로 전달되는 객체이다. rejectWithValue 메서드는 createAsyncThunk 함수에서 비동기 작업이 실패한 경우 사용할 수 있는 메서드로, 에러 객체를 반환하는 대신 사용자가 정의한 값을 반환한다.
따라서 username: id는 axios.post 메서드에서 id 값을 사용하여 username을 설정하는 코드이다. id 값은 위에서 선언된 첫 번째 파라미터(id: string)로부터 전달받은 값이다. 즉, id 값을 username으로 설정하여 API를 호출하게 된다.

 

 

 

 

 

 

 

 

출처
https://velog.io/@coolchaem/ReactTypeScript-APP%EC%9D%98-Redux-%EA%B5%AC%EC%B6%95

 

React(TypeScript) APP의 Redux 구축

토이 프로젝트를 위해 지난번 React(TypeScript) APP을 만들었으나, 상태(state) 관리 라이브러리를 사용하기 위해 Redux를 구축하려고 한다. Redux Redux가 무엇인가? 상태 관리 라이브러리 중 하나이다. redu

velog.io