[React] 웹 게임-4 반응속도체크

ji_silver·2020년 7월 25일
0

[React] 웹 게임

목록 보기
4/8
post-thumbnail

1. React 조건문

  • jsx에서는 for, if문 사용 x -> 삼항연산자 또는 AND(&&) 연산자 사용

ResponseCheck.jsx

renderAverage = () => {
    const { result } = this.state;
    return result.length === 0
        ? null // jsx에서 false, undefined, null은 태그 없음을 의미. 처음엔 null, result에 값이 있으면 랜더링
        : <div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
}

코드가 지저분할 때 이렇게 함수로 랜더링 부분을 분리해도 되지만 새로운 컴포넌트로 만들어 주는 게 더 좋음!

2. setTimeout 넣어 반응속도체크

timeout;
startTime;
endTime;

onClickScreen = () => {
    const { state, message, result } = this.state;
    if (state === 'waiting') {
        this.setState({
            state: 'ready',
            message: '초록색이 되면 클릭하세요.',
        });
        this.timeout = setTimeout(() => {
            this.setState({
                state: 'now',
                message: '지금 클릭',
            });
            this.startTime = new Date(); // state에 넣으면 바뀔 때 마다 랜더링 되기 때문에 this.startTime
        }, Math.floor(Math.random() * 1000) + 2000); // 2초 ~ 3초 중 랜덤
    } else if (state === 'ready') {
        clearTimeout(this.timeout); // 초기화 되지 않고 setTimeout이 실행되기 때문에 삭제하는 코드
        this.setState({
            state: 'waiting',
            message: '너무 성급하시군요! 초록색이 된 후에 클릭하세요.',
        });
    } else if (state === 'now') { // 반응 속도 체크
        this.endTime = new Date();
        this.setState((prevState) => {
            return {
                state: 'waiting',
                message: '클릭해서 시작하세요.',
                result: [...prevState.result, this.endTime - this.startTime],
            };
        });
    }
};

3. 반응속도체크 Hooks로 전환하기

  • this의 속성들을 ref로 표현, ref는 안에 current가 들어 있어서 값을 가져올 때도 뒤에 current를 넣어야함
  • useRef 는 값이 바뀌기는 하지만 화면에 영향을 미치고 싶지 않을 때 사용 (리랜더링 되지 않음)
import React, { useState, useRef } from 'react';

const ResponseCheck = () => {
    const [state, setState] = useState('waiting');
    const [message, setMessage] = useState('클릭해서 시작하세요.');
    const [result, setResult] = useState([]);
    const timeout = useRef(null);
    const startTime = useRef();
    const endTime = useRef();

    const onClickScreen = () => {
        if (state === 'waiting') {
            setState('ready');
            setMessage('초록색이 되면 클릭하세요.');
            timeout.current = setTimeout(() => {
                setState('now');
                setMessage('지금 클릭');
                startTime.current = new Date();
            }, Math.floor(Math.random() * 1000) + 2000);
        } else if (state === 'ready') {
            clearTimeout(timeout.current);
            setState('waiting');
            setMessage('너무 성급하시군요! 초록색이 된 후에 클릭하세요.');
        } else if (state === 'now') {
            endTime.current = new Date();
            setState('waiting');
            setMessage('클릭해서 시작하세요.');
            setResult(prevResult => {
                return [...prevResult, endTime.current - startTime.current];
            });
        }
    };

    const onReset = () => {
        setResult([]);
    };

    const renderAverage = () => {
        return result.length === 0
            ? null
            : <>
                <div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
                <button onClick={onReset}>리셋</button>
            </>
    };

    return (
        <>
            <div id="screen" className={state} onClick={onClickScreen}>
                {message}
            </div>
            {renderAverage()}
        </>
    );
};

export default ResponseCheck;

4. return 내부에 for과 if 쓰기

  • jsx에선 {} 중괄호 사용 시 자바스크립트 코드 사용 가능
  • jsx에선 못 쓰지만 함수 안에서는 for, if문 사용 가능

함수를 선언 하자마자 즉시 실행 하는 함수로 만들어주기

profile
🚧개발중🚧

0개의 댓글