💡
false, undefined, null은 jsx에서 태그없음을 의미한다.
reduce()
의 인자로 빈 배열을 쓸 수 없기 때문에 조건문 처리를 해준다.{/* result에 값이 없으면 null(태그없음), 있으면 div 태그 노출 */}
{this.state.result.length === 0
? null
: <div>평균 시간: {this.state.result.reduce((a, c) => a + c) / this.state.result.length}ms</div>
}
ResponseCheck.jsx
timeout;
startTime;
endTime;
onClickScreen = () => {
const {state, message, result} = this.state;
if(state === 'waiting') {
this.setState({...});
this.timeout = setTimeout(() => { // setTimeout
this.setState({...});
this.startTime = new Date();
}, Math.floor(Math.random() * 1000) + 2000); // 2초~3초 랜덤
} else if (state === 'ready'){ // 성급하게 클릭
clearTimeout(this.timeout); // timeout 삭제 (now 상태로 변하지 않도록)
this.setState({...});
} else if (state === 'now'){ // 반응속도 체크
this.endTime = new Date();
this.setState((prevState) => {
return {
state: 'waiting',
result: [...prevState.result, this.endTime - this.startTime],
message: '클릭해서 시작하세요.'
}
});
}
};
current
로 접근!ReponseCheck.jsx
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); // 2초~3초 랜덤
} else if (state === 'ready'){ // 성급하게 클릭
clearTimeout(timeout.current);
setState('waiting');
setMessage('너무 성급하시군요! 초록색이 된 후에 클릭하세요.');
} else if (state === 'now'){ // 반응속도 체크
endTime.current = new Date();
setState('waiting');
setResult((prevResult) => {
return [...prevResult, endTime.current - startTime.current]
});
setMessage('클릭해서 시작하세요.');
}
};
const renderAverage = () => {
return result.length === 0
? null
: <>
<div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
<button onClick={onReset}>리셋</button>
</>
}
const onReset = () => {
setResult([]);
};
return (
<>
<div
id="screen"
className={state}
onClick={onClickScreen}
>
{message}
</div>
{renderAverage()}
</>
);
}
export default ResponseCheck;
{}
)로 js 함수를 쓸 수 있으므로 즉시실행함수를 선언하여 동작 // 괄호로 감싸고 끝에 ()를 붙여 즉시실행함수로 만든다.
{(() => {
if(result.length === 0){
return null;
} else {
return <>
<div>평균 시간: {result.reduce((a, c) => a + c) / result.length}ms</div>
<button onClick={onReset}>리셋</button>
</>
}
})()}
💡
jsx에서는 배열을 바로 리턴할 수도 있다.// key값 필수! return [ <div key="사과">사과</div>, <div key="배">배</div>, <div key="감">감</div> ];