Redux는 React.js 애플리케이션에서 사용되는 상태 관리 라이브러리로 store를 통해 전역의 state를 관리하고 저장한다. 여기서 더 확장된 RTK는 리덕스(Redux) 상태관리 라이브러리를 사용하기 쉽고 효율적으로 코드를 작성할 수 있도록 돕는 패키지이다.
1) redux와 RTK의 차이
분류 | Redux | RTK |
---|---|---|
코드량 | 많은 코드 양 | 적은 코드 양 |
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를 변경 |
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',
},
});
이전 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,
}; */
감사합니다. 이런 정보를 나눠주셔서 좋아요.