-
Notifications
You must be signed in to change notification settings - Fork 4
Redux와 Typescript를 이용한 상태관리
yellow2041 edited this page Dec 20, 2020
·
4 revisions
- velopert님의 블로그 글을 참고하여 구현하였습니다.
- 사용자가 선택한 콘서트의 정보를 저장하고 있습니다.
- 규모가 크지 않아 모듈 안에서 액션, 액션 생성 함수, 리듀서를 한번에 정의하는 ducks패턴을 사용하였습니다.
- modules/concertInfo.ts
const CHANGE_SELECTED_CONCERT = "concertInfo/CHANGE_SELECTED_CONCERT" as const;
const SELECT_SCHEDULE = "concertInfo/SELECT_SCHEDULE" as const;
const SET_CLASS_INFO = "concertInfo/SET_CLASS_INFO" as const;
export const changeSelectedConcert = (id: string, name: string) => ({
type: CHANGE_SELECTED_CONCERT,
payload: { id, name },
});
export const selectSchedule = (id: string, dateDetail: string) => ({
type: SELECT_SCHEDULE,
payload: { id, dateDetail },
});
export const setClassInfo = (prices: Object, colors: Object) => ({
type: SET_CLASS_INFO,
payload: { prices, colors },
});
export interface ConcertInfo {
id: string;
name: string;
scheduleId?: string;
dateDetail: string;
prices: any;
colors?: any;
startDate?: string;
endDate?: string;
runningTime?: string;
class?: string;
}
type ConcertInfoAction =
| ReturnType<typeof changeSelectedConcert>
| ReturnType<typeof selectSchedule>
| ReturnType<typeof setClassInfo>;
type ConcertInfoState = ConcertInfo;
const initialState: ConcertInfoState = {
id: "",
name: "",
scheduleId: undefined,
dateDetail: "",
prices: {},
colors: undefined,
startDate: undefined,
endDate: undefined,
runningTime: "",
class: "",
};
const concertInfoReducer = (
state: ConcertInfoState = initialState,
action: ConcertInfoAction,
): ConcertInfoState => {
switch (action.type) {
case CHANGE_SELECTED_CONCERT:
return {
...state,
id: action.payload.id,
name: action.payload.name,
};
case SELECT_SCHEDULE:
return {
...state,
scheduleId: action.payload.id,
dateDetail: action.payload.dateDetail,
};
case SET_CLASS_INFO:
return {
...state,
prices: { ...action.payload.prices },
colors: { ...action.payload.colors },
};
default:
return state;
}
};
export default concertInfoReducer;
- modules/index.ts (루트리듀서 등록)
import { combineReducers } from "redux";
import concertInfoReducer from "./concertInfo";
import socketReducer from "./socket";
import userReducer from "./user";
const rootReducer = combineReducers({
concertInfoReducer,
userReducer,
socketReducer,
});
export default rootReducer;
export type RootState = ReturnType<typeof rootReducer>;
- hooks/useConcertInfo.ts
- concertInfo의 상태를 자주 사용하기 때문에 hook을 만들어 사용하였습니다.
import { useSelector } from "react-redux";
import { RootState } from "../modules";
export default function useConcertInfo() {
const concertInfo = useSelector((state: RootState) => state.concertInfoReducer);
return concertInfo;
}
- typescript의 장점을 활용하기 위해 interface 정의를 더 구체적으로 하기
ex)
export interface ConcertInfo {
id: string;
name: string;
scheduleId?: string;
dateDetail: string;
prices: any;
colors?: any;
startDate?: string;
endDate?: string;
runningTime?: string;
class?: string;
}
이 부분의 개선 필요.
- 처음에 redux 활용을 잘못해서 socket의 이벤트 등록과 관련된 부분을 context API로 대체하게 되었는데, 이 부분은 다시 redux로 대체 가능 할 것 같다.