[React Native] Redux, createAsyncThunk 비동기 작업 구현

이지민·2025년 1월 28일
0

ReactNative

목록 보기
11/12

Redux란?

JavaScript 기반의 상태관리 라이브러리이다. jotai, recoil등 다양한 상태관리 라이브러리가 있다. 어플리케이션의 상태를 중앙에서 관리하고, 그 상태를 업데이트하고 사용하는 라이브러리이다.

라이브러리 설치

npm install react-redux
npm install @reduxjs/toolkit

Redux의 주요개념

Store(상태 저장소):

  • Redux의 상태는 Store에 저장된다.
  • 어플리케이션의 상태는 하나의 전역 상태 트리로 구성된다.
  • 어플리케이션 전체에서 상태가 공유되며, store를 통해 상태를 관리한다.

Action(액션):

  • Action은 상태를 변경하는 신호
  • 상태를 어떻게 변화시킬지 정보를 가지고 있다.

Reducer(리듀서):

  • Reducer는 상태를 어떻게 변화시킬지를 정의하는 함수이다.
  • 액션을 받아서 이전 상태를 기반으로 새로운 상태를 반환한다.
  • 리듀서는 순수 함수여야 하며, 이전 상태와 액션을 인자로 받아 새로운 상태를 반환한다.

Redux 흐름

1. Action 발생
사용자 인터페이스나 다른 부분에서 Action을 발생시킨다. 예를 들어, 버튼을 클릭하거나 서버 응답을 받았을 때 액션을 생성할 수 있다.

2. Action을 Store로 전달
액션은 Dispatch를 통해 Store로 전달된다. store.dispatch(action)을 사용하여 액션을 발송한다.

3. Reducer 실행
액션을 받은 Reducer는 현재 상태와 액션을 기반으로 새로운 상태를 반환한다.

4. State 업데이트
새로 반환된 상태는 Store에 저장되고, 이로 인해 컴포넌트들이 새로 업데이트된다. Redux는 상태가 변경될 때 관련된 컴포넌트가 자동으로 리렌더링되도록 한다.

Redux Toolkit

액션 생성, 리듀서 설정을 간소화하고 기본적인 설정을 자동화한 라이브러리

import { createSlice, configureStore } from '@reduxjs/toolkit';

// 상태 정의
const initialState = {
  items: [],
};

// 슬라이스 생성
const itemsSlice = createSlice({
  name: 'items',
  initialState,
  reducers: {
    addItem: (state, action) => {
      state.items.push(action.payload);
    },
  },
});

// 액션과 리듀서를 자동으로 생성
export const { addItem } = itemsSlice.actions;

// 스토어 설정
const store = configureStore({
  reducer: {
    items: itemsSlice.reducer,
  },
});

export default store;

비동기 작업 처리 (Thunk)

Redux는 동기로 작업을 처리하는데, api와 같은 비동기 작업 처리가 필요한 액션들을 위해 redux-thunk라는 미들웨어를 사용해서 처리한다.

여기서는 createAsyncThunk를 이용해서 처리한다.

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

export const fetchItems = createAsyncThunk(
  'items/fetchItems',
  async () => {
    const response = await fetch('/api/items');
    return response.json();
  }
);

const itemsSlice = createSlice({
  name: 'items',
  initialState: { items: [], status: 'idle' },
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(fetchItems.pending, (state) => {
      state.status = 'loading';
    });
    builder.addCase(fetchItems.fulfilled, (state, action) => {
      state.status = 'succeeded';
      state.items = action.payload;
    });
    builder.addCase(fetchItems.rejected, (state) => {
      state.status = 'failed';
    });
  },
});

export default itemsSlice.reducer;
profile
개발자가 되고싶어요

0개의 댓글