Redux Toolkit을 사용한 전역 상태 관리

MODAC·2023년 8월 18일
0

knockknock

목록 보기
4/9

1. Redux ToolKit

Redux는 React.js 애플리케이션에서 사용되는 상태 관리 라이브러리로 store를 통해 전역의 state를 관리하고 저장한다. 여기서 더 확장된 RTK는 리덕스(Redux) 상태관리 라이브러리를 사용하기 쉽고 효율적으로 코드를 작성할 수 있도록 돕는 패키지이다.

1) redux와 RTK의 차이

분류ReduxRTK
코드량많은 코드 양적은 코드 양
Immutable 추가Immutable 업데이트 미지원Immutable 업데이트 지원
createSlice 함수 추가상태, 액션, 리듀서를 각각 개별적으로 작성createSlice 함수로 상태, 액션, 리듀서를 한 번에 생성
configureStore 함수 추가스토어 생성 코드를 따로 작성configureStore 함수로 스토어 생성 코드 자동 생성
기본적인 미들웨어 포함기본 미들웨어 미포함몇 가지 기본 미들웨어 포함

2) 메서드 정리

메서드 설명
configureStore()Redux Store를 구성하는 메서드로, reducer 및 middleware를 설정하고 store를 반환
createReducer()일반적인 reducer 함수를 작성하는 데 사용
createAction()일반적인 액션 생성 함수를 작성하는 데 사용
createSlice()Redux Toolkit에서 reducer를 작성하는 유틸리티 메서드로 초기 상태 및 reducer 함수를 정의하고, 액션 생성 함수 생성.
createAsyncThunk()비동기 작업을 수행하는 Action Creator를 생성
createEntityAdapter()비정규화된 엔티티 데이터를 쉽게 관리
createSelector()Reselect 라이브러리와 함께 사용하여 성능 최적화된 셀렉터를 생성
useSelector()Redux store에서 state를 불러오는 메서드
useDispatch()Redux store에서 action을 dispatch하는 Hook으로 컴포넌트에서 Redux store의 state를 변경

2. Store & Slice 구성 및 Provider 설정

state의 초기값을 설정하고 state에 맞는 action을 세팅한다.

//userSlice.ts
import {createSlice} from '@reduxjs/toolkit';

const initialState = {
  nickName: '',
  email: '',
  userId: '',
  accessToken: '',
};

export const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {
    // 모든 사용자 정보 저장
    setUser(state, action) {
      state.nickName = action.payload.name;
      state.email = action.payload.email;
      state.userId = action.payload.userId;
    },
    setNickName(state, action) {
      state.nickName = action.payload;
    },
    setEmail(state, action) {
      state.email = action.payload;
    },
    setUserId(state, action) {
      state.userId = action.payload;
    },
    setAccessToken(state, action) {
      state.accessToken = action.payload;
    },
  },
});

export const {setUser, setNickName, setEmail, setUserId, setAccessToken} = userSlice.actions;
export default userSlice;

애플리케이션 상태를 담고 있는 객체인 Store를 구성한다.

//store.ts
import {configureStore} from '@reduxjs/toolkit';
import userSlice from './userSlice';

const store = configureStore({
  reducer: {
    user: userSlice.reducer,
  },
});

export default store;

App 페이지 최상위에 Provider로 스토어를 등록한다.

//최상위 app.tsx
import {View, StyleSheet} from 'react-native';
import {NavigationContainer, DefaultTheme} from '@react-navigation/native';
import {AuthStack} from './src/navigations/StackNavigator';
import {Provider} from 'react-redux';
import store from './src/util/redux/store';

const App = () => {
  return (
    <Provider store={store}>
      <NavigationContainer
        theme={{
          ...DefaultTheme,
          colors: {
            ...DefaultTheme.colors,
            background: 'white',
          },
        }}
        independent={true}>
        <View style={styles.container}>
          <AuthStack />
        </View>
      </NavigationContainer>
    </Provider>
  );
};

export default App;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#ffffff',
  },
});

3. Redux Toolkit으로 state 관리하기

이전 splash와 login screen에서 AsyncStrage에 토큰 정보를 저장했는데 로그인 시 사용될 userId와 nickname, email, Authorization bearer token에 전달할 accessToken을 전역 state에 저장하여 유저 정보가 포함된 모든 요청에 가져와서 사용한다.

// login.tsx
//...중략
import {useDispatch} from 'react-redux';
import {setUserId, setAccessToken} from '../../util/redux/userSlice';

const dispatch = useDispatch();
const loginAuth = async () => {
    if (url !== undefined) {
      try {
        const response = await axios.post(`${url}api/v1/users/login`, data);
        const {accessToken, refreshToken, userId} = response.data;
        // 자동 로그인 정보 수집
        if (autoLogin) {
          await storageSetValue('tokens', {accessToken, refreshToken});
        } else await storageDeleteValue('tokens');
        // store에 userId와 토큰 저장
        dispatch(setUserId(userId)); // userId 저장
        dispatch(setAccessToken(accessToken)); // 엑세스토큰 저장
        //메인화면으로 이동
        navigation.navigate('MainTab');
      } catch (error: any) {
        navigation.reset({routes: [{name: 'Login'}]});
      }
    }
  };

//component.tsx
import {useSelector} from 'react-redux';

  const user = useSelector((state: any) => state.user);
  console.log(user);
/* {
  accessToken: 'your accessToken',
  email: '',
  nickName: '',
  userId: 1,
}; */

2개의 댓글

comment-user-thumbnail
2023년 8월 18일

감사합니다. 이런 정보를 나눠주셔서 좋아요.

1개의 답글
Powered by GraphCDN, the GraphQL CDN