React

 

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

리액트

 

about author

PHRASE

Level 60  라이트

인간의 약점은 특권의식이다. 특권의식을 자극하면 누구나 쉽게 흔들린다. -이드리스 샤흐

댓글 ( 0)

댓글 남기기

작성