
game-jam-2020.kucc.co.kr/의 참가 신청 버튼을 누르면 '신청이 마감되었습니다.' 라는 토스트 메세지가 뜨도록 만들었다.
일단 토스트 컴포넌트에서 고려해야 할 것들을 먼저 생각했다.
- 버튼을 누르면 보이기
- 일정 시간이 지나면 숨겨지기
- 보이고 숨겨질 때 애니메이션 넣기
토스트 컴포넌트 자체에 isActive (지금 메세지가 보이고 있는지) 라는 state를 넣으려고 했는데, 버튼으로 조작해야 하고, 이 페이지에서 토스트 메세지는 여기에서만 쓰니까 일단 페이지에 state를 만들었다.
const [isActive, setIsActive] = useState(false);
<Toast isActive={isActive} setIsActive={setIsActive} message="신청이 마감되었습니다." /> <S.JoinButton onClick={() => {setIsActive(true);}}> 참가 신청 </S.JoinButton>
토스트 컴포넌트에는 페이지에서 만들어준 state랑 state 세팅 함수를 props로 넘겨준다.
그리고 버튼을 누르면 isActive가 true가 되도록 했다.
import React, { useEffect } from "react"; import * as S from "./styles"; interface ToastProps { message: string; isActive: boolean; setIsActive: (a: boolean) => void; } const Toast: React.FC<ToastProps> = ({ message, isActive, setIsActive }) => { useEffect(() => { if (isActive === true) setTimeout(() => { setIsActive(false); }, 3000); }); return <>{isActive ? <S.Toast show={true}>{message}</S.Toast> : <S.Toast show={false} />}</>; }; export default Toast;
useEffect에서는 isActive가 업데이트될 때, 만약 isActive가 true라면 3000ms 뒤에 isActive를 false로 바꿔준다.
그리고 css에서 애니메이션을 넣고, isActive가 false일 때 안 보이게 해줄 것이다.
const fadein = keyframes` 0% { top: 0px; opacity: 0; } 100% { top: -30px; opacity: 1; } `; const fadeout = keyframes` 0% { top: -30px; opacity: 1; } 100% { top: 0px; opacity: 0; } `; interface SnackbarProps { show: boolean; } export const Snackbar = styled.div<SnackbarProps>` z-index: 100; position: absolute; visibility: ${(props) => (props.show ? "visible" : "hidden")}; background-color: #333; color: #fff; text-align: center; border-radius: 30px; padding: 1rem; padding-left: 1.5rem; padding-right: 1.5rem; font-size: 1.6rem; -webkit-animation: ${(props) => props.show ? css` ${fadein} 0.5s, ${fadeout} 0.5s 2.5s ` : ""}; animation: ${(props) => props.show ? css` ${fadein} 0.5s, ${fadeout} 0.5s 2.5s ` : ""}; animation-fill-mode: forwards; `;
props로 show 인자를 받아오는데, 여기엔 isActive가 들어올 것이다.
show의 T/F 여부에 따라 visibility를 visible과 hidden으로 해주면 된다.
애니메이션도 show의 T/F 여부에 따라 넣어주는데, fadein은 아래에서 위로 올라오면서 불투명도가 점점 커지고, fadeout은 반대다.
0.5초동안은 fadein 애니메이션을 보여주고, 2.5초 delay된 fadeout 애니메이션을 0.5초 보여줘서 총 3초동안 fadein-내용표시-fadeout이 연결되게 한다.
끝~!
'Web > Frontend' 카테고리의 다른 글
[Next JS] Next JS 시작하기 (4) | 2021.02.06 |
---|---|
[리액트] Scroll indicator 만들기 (2) | 2020.10.31 |
[리액트] 이미지 업로더 - 서버에 이미지 Post로 보내기 (2) | 2020.07.20 |
[리액트] 드래그 앤 드롭, 리사이징 리스트 만들기 (2) | 2020.06.02 |
[리액트] 수정 가능한 텍스트 박스 만들기 (1) | 2020.05.25 |
댓글