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)
댓글 남기기