React toast 팝업 구현

김용희·2024년 4월 17일

[project] Art Friendly

목록 보기
12/14

구현 원리 및 내용

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의 상태를 가져와 상태에 따른 다른 문구를 출력합니다.

0개의 댓글