Meditation.tsx
가장 먼저 볼 파일은
Meditation.tsx 파일입니다. 최상단 파일로 다른 하위 컴포넌트들을 순서대로 렌더링하는 역할을 합니다.하위 컴포넌트
Container
페이지 전체를 감싸는 스타일 컴포넌트 입니다.
MeditationLabel
명상을 시작합니다. 편안한 명상되세요. 등 명상 도중 사용자의 안내를 돕기 위한 문구를 표시하는 컴포넌트입니다.
MeditationTimer
명상을 시작, 종료 하고 명상의 남은 시간을 알려주는 컴포넌트입니다.
MeditationCounter
명상을 시작하기 전, 시간을 설정할 수 있는 컴포넌트입니다.
Confirm
명상 끝내기 버튼 을 클릭하면 나타나는 확인창입니다.알아야 할 점
MeditationCounter 는 시간을 세팅하고, MeditationTimer 는 MeditationCounter 에서 세팅한 시간을 가져와서 사용해야 합니다. 따라서 recoil 로 시간을 전역적으로 다뤄줘야 합니다.MeditationLabel.tsx
사용자의 명상 안내를 돕기 위한 컴포넌트입니다.
필요한 문구를 상수로 처리해놓습니다.
각 상수를 보여주기 위해 label state 를 사용합니다.
그리고 각 문구를 트리거할 이벤트를 Counter, Timer, EndButton 등 다른 컴포넌트에서 선언해 놓습니다. (추후 설명)
Label 컴포넌트에서는 각 이벤트가 발생하면 이를 감지하여
setLabel 함수를 통해 새로 label 을 렌더링합니다.MeditationCounter.tsx
MeditationTimer 가 더 위에 선언되었지만 유저의 행동은 MeditationCounter 를 거쳐야 하므로 Counter 파일을 먼저 살펴봅니다.state
- time
사용자가 설정한 명상 시간입니다. MeditationTimer 와 공유해야 하는 값이 바로 이 값입니다. 따라서 Recoil 로 설정해줍니다.
- timerStarted
타이머가 시작했을 때 상태를 체크하기 위한 값입니다.
- timerEnded
타이머가 끝났을 때 상태를 체크하기 위한 값입니다.
useEffect
시작 버튼을 누를 때, 명상이 끝날 때를 이벤트로 관리해줍니다.
- 명상 시작 시
timerStarted 를 true 로 바꾸어줍니다.- 명상 종료 시
timerEnded 를 true 로 바꾸어줍니다.명상이 시작 되기 전 렌더링
타이머가 시작되기 전 (
!timerStarted) 엔 아래 사진과 같이 시간을 설정할 수 있는 컴포넌트 보여줍니다.
handleTime 함수
이전 버튼을 클릭하게 되면
BUTTON_TYPE_SUB 을,다음 버튼을 클릭하게 되면
BUTTON_TYPE_ADD 를 넘겨줍니다.넘어오는 타입에 따라서 시간을 증가하거나 감소하는 함수입니다.
명상 시작 후 렌더링
명상 시작 후엔 명상을 끝내는 버튼을 보여줘야 하므로 다음과 같이 조건문으로 버튼을 보여줍니다.
MeditationEndButton.tsx
명 종료 버튼을 누르면 명상을 종료하겠냐고 Confirm 창을 보여주기 위해 recoil 로 state 를 만듭니다.
렌더링 시에는 버튼을 누르면 end 버튼이 클릭되었다는 함수만 붙여주면 됩니다.
Meditation root 페이지에서 다음과 같이 호출하기 때문
MeditationTimer.tsx
렌더링
- hover 시엔 플레이버튼 & 일시정지 버튼을 보여줘야 하기 때문에
hovered를 state 로 만들어서 관리합니다.
- hover 중에서도
paused가true일 땐 플레이버튼, 아닐 경우 일시정지 버튼을 보여줍니다.
- hover 가 아니라면 남은 시간을 보여줍니다.
상태
따라서 필요한 상태는 다음과 같습니다. meditationTime 은 Counter 에서도 설정할 수 있어야 하기 때문에 recoil 로 관리합니다.
타이머 클릭 이벤트 - toggleTimer()
- 타이머가 정지된 상태가 아니라면 (
!puased) 타이머를 정지 시킵니다.
그리고 정지상태 (paused) 를
true 로 설정합니다.- 타이머가 정지된 상태라면 타이머를 재시작합니다.
타이머 재시작 - startTimer()
타이머 시간을 1초씩 감소시키는 함수입니다.
1초마다 실행되는 setInterval 내부 콜백은 다음과 같습니다.
preveTime > 0
시간이 남은 경우 시간을 1초씩 감소시킵니다.
- 시간이 종료된 경우 타이머를 취소하고, 타이머가 끝났다는 이벤트를 발생시킵니다.
