과거 프로그래밍 자료들/React
[웹 게임을 만들며 배우는 React] - 반응속도 체크, state와 ref 차이
평부
2022. 9. 28. 16:43
출처: https://www.inflearn.com/course/web-game-react/dashboard
* class 사용
[ResponseCheckClass.jsx]
import React, { Component } from "react";
class ResponseCheckClass extends Component {
state = {
state: "waiting",
message: "클릭해서 시작하세요.",
result: [],
};
timeout;
startTime;
endTime;
onClickScreen = () => {
const { state } = this.state;
if (state === "waiting") {
this.timeout = setTimeout(() => {
this.setState({
state: "now",
message: "지금 클릭",
});
this.startTime = new Date();
}, Math.floor(Math.random() * 1000) + 2000); // 2초~3초 랜덤
this.setState({
state: "ready",
message: "초록색이 되면 클릭하세요.",
});
} else if (state === "ready") {
// 성급하게 클릭
clearTimeout(this.timeout);
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],
};
});
}
};
onReset = () => {
this.setState({
result: [],
});
};
renderAverage = () => {
const { result } = this.state;
console.log(result);
return result.length === 0 ? null : (
<>
<div>
평균 시간 : {result.reduce((a, c) => a + c) / result.length}
ms
</div>
<button onClick={this.onReset}>리셋</button>
</>
);
};
render() {
const { state, message } = this.state;
return (
<>
<div id="screen" className={state} onClick={this.onClickScreen}>
{message}
</div>
{this.renderAverage()}
</>
);
}
}
export default ResponseCheckClass;
* Hooks 사용 (state와 ref 차이)
- state : 아래의 setState, setMessage, setResult 하면 리턴(return)이 다시 실행됨(렌더링됨)
- ref : 값이 바뀌어도 리턴 부분이 다시 실행되지 않음(화면에 영향을 미치지 않음)
▶ 주로 timeout, interval에 사용
▶ ref는 current로 접근(아래의 예시에서 current가 없으면 값이 NaN으로 나옴)
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(0);
const endTime = useRef(0);
const onClickScreen = () => {
if (state === "waiting") {
timeout.current = setTimeout(() => {
setState("now");
setMessage("지금 클릭");
startTime.current = new Date();
}, Math.floor(Math.random() * 1000) + 2000); // 2초~3초 랜덤
setState("ready");
setMessage("초록색이 되면 클릭하세요.");
} else if (state === "ready") {
// 성급하게 클릭
clearTimeout(timeout);
setState("waiting");
setMessage("너무 성급하시군요! 초록색이 된 후에 클릭하세요.");
} else if (state === "now") {
// 반응속도 체크
endTime.current = new Date();
setState("waiting");
setMessage("클릭해서 시작하세요.");
setResult((prevResult) => [
...prevResult,
endTime.current - startTime.current,
]);
}
};
const onReset = () => {
setResult([]);
};
const renderAverage = () => {
console.log(result);
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;