TimerChallenge.jsx
import React, { useEffect, useRef, useState } from 'react' import ResultModal from './ResultModal'; const TimerChallenge = ({title, targetTime}) => { const timer =useRef(); const dialog=useRef(); const [timeRemaining, setTimeRemaining] = useState(targetTime*1000); const timerIsActive =timeRemaining > 0 && timeRemaining < targetTime*1000; useEffect(()=>{ if(timeRemaining <= 0 ) { clearInterval(timer.current); dialog.current.open(); } }, [timeRemaining]); function handleReset(){ setTimeRemaining(targetTime*1000); } function handleStart(){ timer.current=setInterval(() =>{ setTimeRemaining(prevTimeRemaining => prevTimeRemaining-10); }, 10); } function handleStop(){ dialog.current.open(); clearInterval(timer.current); } return ( <> <ResultModal ref={dialog} targetTime={targetTime} timeRemaining={timeRemaining} result ="YOU LOST" onReset={handleReset} /> <section className='challenge'> <h2>{title}</h2> {/* {timerExpired && <p>You lost! </p>} */} <p className='challenge-time'> {targetTime} 초 {targetTime >1 ? '' :''} </p> <p> <button onClick={timerIsActive ?handleStop :handleStart}> {timerIsActive ? '멈추기' : '시작하기'} </button> </p> <p className={timerIsActive ? 'active' : undefined}> {timerIsActive ? '타이머 작동중...' : '타이머 비활성' } </p> </section> </> ) } export default TimerChallenge
ResultModal.jsx
import {forwardRef, useImperativeHandle, useRef} from 'react' import {createPortal} from 'react-dom'; const ResultModal = forwardRef (({result, targetTime, timeRemaining , onReset} , ref) => { const dialog=useRef(); const userLost=timeRemaining <=0; const formmaterdRemainingTime=(timeRemaining /1000).toFixed(2); const score = Math.round(( 1- timeRemaining/ (targetTime *1000) ) * 100); useImperativeHandle(ref, ()=>{ return{ open(){ dialog.current.showModal(); } } }) return createPortal( <dialog ref={dialog} className='result-modal' onClose={onReset}> {userLost && <h2> {result}</h2>} {!userLost && <h2>{score}점 입니다.</h2>} <p>목표 시간은 <strong>{targetTime} 초 였습니다.</strong></p> {timeRemaining >1 && <p> <strong>{formmaterdRemainingTime} 초 남았는데 타이머를 멈췄습니다. </strong></p> } <form method='dialog' onSubmit={onReset}> <button>닫기</button> </form> </dialog>, document.getElementById("modal") ); }) export default ResultModal
index.html
~ <body> <div id="modal"></div> <div id="content"></div> <script type="module" src="/src/main.jsx"></script> ~
소스 :
https://github.com/braverokmc79/react-final-count
https://react-final-coun.netlify.app/
6.리액트 - 프로젝트 관리 앱 프로젝트 관리 앱
https://macaronics-project-management-app.netlify.app/
https://github.dev/braverokmc79/react-project-management-app
댓글 ( 0)
댓글 남기기