React로 스톱워치 만들기

이번에는 React JS를 이용해 스톱워치를 만들어보자.

컴포넌트 구성

const { centisecond, start, pause, createLap, reset, isRunning, laps } =
        useTimer();

<section className="w-fit bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 flex flex-col justify-center m-auto mt-36 max-w-sm">
            <Timer centisecond={centisecond} />
            <div className="flex justify-between text-white pb-8 text-sm select-none">
                <Button
                    color="bg-gray-600"
                    label={isRunning === true ? '' : '리셋'}
                    code="L"
                    handleBtnClick={handleLapRest}
                    ref={lapResetRef}
                />
                <Button
                    color={isRunning === true ? 'bg-red-600' : 'bg-green-600'}
                    label={isRunning === true ? '중단' : '시작'}
                    code="S"
                    handleBtnClick={handleStartStop}
                    ref={startStopRef}
                />
            </div>
            <Laps laps={laps} />
        </section>

시작/중단, 랩/리셋 기능 만들기

const handleStartStop = () => {
        if (isRunning === false) {
            start();
        } else {
            pause();
        }
    };
    const handleLapRest = () => {
        if (isRunning === false) {
            reset();
        } else {
            createLap();
        }
    };

<Button
    color={isRunning === true ? 'bg-red-600' : 'bg-green-600'}
    label={isRunning === true ? '중단' : '시작'}
    code="S"
    handleBtnClick={handleStartStop}
    ref={startStopRef}
/>

랩 기능 구현

키보드 조작 기능 구현

const handleKeyDown = (e) => {
        if (e.code === 'KeyL') {
            lapResetRef.current.click();
        } else if (e.code === 'KeyS') {
            startStopRef.current.click();
        }
};
useEffect(() => {
    document.addEventListener('keydown', (e) => handleKeyDown(e));
}, []);

최단, 최장 기록 강조 기능 구현

const Laps = ({ laps }) => {
    const sortedLaps = [...laps].sort((lap1, lap2) => lap1[1] - lap2[1]);
    const maxLapNum = sortedLaps.length && sortedLaps[sortedLaps.length - 1][0];
    const minLapNum = sortedLaps.length && sortedLaps[0][0];

    const createMinMaxStyle = (lap) => {
        if (laps.length < 2) return;
        if (lap[0] === minLapNum) return 'text-green-600';
        else if (lap[0] === maxLapNum) return 'text-red-600';
    };

    return (
        <article className="text-gray-600 h-64 overflow-auto border-t-2">
            <ul id="laps">
                {/* 추가되는 lap은 아래의 HTML 코드 형식을 사용해 추가해주세요.  */}
                {laps.map((lap) => (
                    <li
                        className={`${createMinMaxStyle(
                            lap
                        )} flex justify-between py-2 px-3 border-b-2`}
                        key={lap[0]}
                    >
                        <span> {lap[0]}</span>
                        <span>{formatTime(lap[1])}</span>
                    </li>
                ))}
            </ul>
        </article>
    );
};

완성본

완성본 보러가기

끝!