구현 원리 및 내용
1. 토스트 팝업 상태 관리
- 토스트의 상태를 boolean 값으로 관리하여 좋아요 버튼을 누를 시 토스트 팝업이 뜨게 합니다.
import { type PayloadAction, createSlice } from '@reduxjs/toolkit';
import { type RootState } from 'store';
interface StateType {
toast: boolean;
}
const initialState: StateType = {
toast: false
};
export const toastSlice = createSlice({
name: 'toast',
initialState,
reducers: {
active: (state, action: PayloadAction<boolean>) => {
state.toast = action.payload;
},
},
});
export const toastActions = toastSlice.actions;
export const selectToast = (state: RootState) => state.toast.toast;
export default toastSlice.reducer;
- 여러 컴포넌트에서 토스트 팝업을 사용하기 위해 리덕스로 상태를 관리하였습니다.
- active 리듀서로 상태를 변경합니다.
const favoriteBtnHandler = () => {
setIsFavorite((prev) => !prev);
dispatch(toastActions.active(true));
};
- dispatch로 좋아요 버튼을 눌렀을 때 토스트 팝업의 상태를 true로 변경합니다.
const NavigationBar = () => {
const toast = useAppSelector(selectToast);
return (
<div className="relative flex w-full shadow-custom h-1/10 rounded-t-2xl">
{navigations.map((navigation) => (
<NavigationBtn
key={navigation.name}
name={navigation.name}
endpoint={navigation.endpoint}
inActiveIcon={navigation.inActiveIcon}
activeIcon={navigation.activeIcon}
/>
))}
{toast ? <Toast /> : null}
</div>
);
};
- useSelector로 토스트의 상태를 불러와 화면에 띄웁니다.
- 여러 컴포넌트에서 재사용하기 위해 네비게이션바 바로 위에 토스트 팝업을 띄울 수 있도록 하였습니다.
2. 토스트 팝업이 일정시간 이후에 사라지도록 설정
- setTimeout을 사용하여 일정시간 이후에 토스트 팝업 활성화 상태가 해제되도록 합니다.
const favoriteBtnHandler = () => {
setIsFavorite((prev) => !prev);
dispatch(toastActions.active(true));
setTimeout(() => {
dispatch(toastActions.active(false));
}, 2000);
};
3. 좋아요 등록, 취소에 따른 다른 문구 출력
- 좋아요 등록, 취소에 대한 상태도 토스트 팝업에 전달하여 각자 다른 문구 및 디자인을 출력합니다.
import { type PayloadAction, createSlice } from '@reduxjs/toolkit';
import { type RootState } from 'store';
interface StateType {
toast: boolean[];
}
const initialState: StateType = {
toast: [false, false],
};
export const toastSlice = createSlice({
name: 'toast',
initialState,
reducers: {
active: (state, action: PayloadAction<boolean>) => {
state.toast[0] = action.payload;
},
isFavorite: (state, action: PayloadAction<boolean>) => {
state.toast[1] = action.payload;
},
},
});
export const toastActions = toastSlice.actions;
export const selectToast = (state: RootState) => state.toast.toast;
export default toastSlice.reducer;
- 리덕스에 상태를 변경하였습니다.
- isFavorite 리듀서를 추가하여 좋아요 등록, 취소 상태를 구분할 수 있도록 하였습니다.
const favoriteBtnHandler = () => {
setIsFavorite((prev) => !prev);
dispatch(toastActions.isFavorite(isFavorite));
dispatch(toastActions.active(true));
setTimeout(() => {
dispatch(toastActions.active(false));
}, 2000);
};
- 좋아요 버튼을 눌렀을 때 좋아요의 등록 또는 취소의 상태도 전달합니다.
onst Toast = () => {
const isFavorite = useAppSelector(selectToast)[1];
return (
<div
className={`absolute -top-14 flex items-center justify-center h-12 left-[5%] w-9/10 rounded-3xl opacity-80 animate-appear-toast ${isFavorite ? 'bg-gray-60' : 'bg-purple-90'}`}
>
<span className="text-white text-Body3-120">
{isFavorite
? '좋아요를 취소했어요.'
: '좋아요를 했어요. 캘린더에서 확인해보세요!'}
</span>
</div>
);
};
- 토스트 컴포넌트 내부에서 isFavorite의 상태를 가져와 상태에 따른 다른 문구를 출력합니다.