안녕하세요 Foma 입니다!
이전 글에서 Redux에 대해 다뤘는데요.
오늘은 그 Redux를 이용해 간단한 Counter 앱을 만들어 보려고 합니다.
바로 시작할게요~
(환경은 React Natvie CLI, Typescript로 진행하겠습니다.)
Preview
Install
Typescript Project Init
npx react-native init "프로젝트 이름" --template react-native-template-typescript
redux
npm install redux
react-redux
npm install react-redux
@types/react-native
npm install @types/react-native
Counter
가장 먼저 카운터 인터페이스를 만들어 줍니다.
interface Counter {
count: number;
}
Action
액션이 일어날 종류(증가,감소) CounterActinoType과 Action을 정의할 CounterAction 타입을 만들어 줍니다.
export enum CounterActionType {
increment,
decrement,
}
export type CounterAction = {
type: CounterActionType;
payload: Counter;
};
Reducer
Reducer를 통해서 액션의 종류에 따라 상태(state)가 바껴서 반환되도록 만들어 줍니다.
action의 종류가 increment라면 이전 상태에서 count를 + 1 해주고, decrement라면 이전 상태에서 count - 1을 해준 뒤 새로운 state를 반환합니다.
const initialState: Counter = {
count: 0,
};
const counterReducer = (
state: Counter = initialState,
action: CounterAction,
): Counter => {
switch (action.type) {
case CounterActionType.increment:
return {
...state,
count: state.count + 1,
};
case CounterActionType.decrement:
return {
...state,
count: state.count - 1,
};
default:
return state;
}
};
Store
redux의 combinReducers를 이용해 위에서 만들어준 counterReducer를 rootReducer로 합쳐 줍니다.
그리곤 가장 초기의 상태인 RootState 타입을 만들어 줍니다.
export const rootReducer = combineReducers({
counter: counterReducer,
});
export type RootState = ReturnType<typeof rootReducer>;
Screen
다음은 스크린을 만들어 주는데, useDispatch를 이용하여 Action에 대한 dispatch를 관찰하고,
useSelector를 이용하여 Reducer로 만든 counter의 counter 상태를 받아옵니다.
const Home = () => {
const dispatch = useDispatch();
const count = useSelector<RootState>(state => state.counter.count);
...
그 다음 CounterActionType에 따라 CounterAction을 만들어 주고 dispatch로 해당 Action을 보냅니다.
function act(type: CounterActionType) {
let counter: Counter = {count: Number(count)};
let action: CounterAction = {
type: type,
payload: counter,
};
dispatch(action);
}
View는 아래와 같이 count를 나타낼 Text와 increment,decrement를 할 Pressable을 만들어 줍니다.
return (
<View>
<Text style={styles.count}> {count} </Text>
<Pressable
onPress={() => {
act(CounterActionType.increment);
}}>
<Text style={styles.increment}>Increment</Text>
</Pressable>
<Pressable
onPress={() => {
act(CounterActionType.decrement);
}}>
<Text style={styles.decrement}>Decrement</Text>
</Pressable>
</View>
);
Styles
const styles = StyleSheet.create({
count: {
textAlign: 'center',
fontSize: 30,
fontWeight: '600',
margin: 20,
padding: 5,
color: 'black',
},
increment: {
textAlign: 'center',
fontSize: 20,
color: 'white',
margin: 20,
borderRadius: 10,
padding: 20,
backgroundColor: '#B32134',
},
decrement: {
textAlign: 'center',
fontSize: 20,
color: 'white',
margin: 20,
borderRadius: 10,
padding: 20,
backgroundColor: '#0096FF',
},
});
느낀 점
평소 iOS를 개발할 때 Reactorkit으로 개발한 경험이 있어서 생각보다 익숙했다.
또 Redux를 사용하기 전에는 Component로 기능을 전달하고 CallBack 함수로 다시 받아서 원하는 Component에 기능이 작동하도록 했는데... 진심 너무 불편했다.
하지만 Redux를 사용해서 한 곳에서 State를 관리하여 여러 Component에서 사용하니 너무 간편했다.
앞으로 Redux에 대해 더 공부해 봐야겠다.
Source Code
댓글