※ 프로젝트는 create-react-app 으로 시작 ※
import React, { useRef, useState } from 'react';
import Container from "./Container";
import Blocks from "./Blocks";
function makeRandom() {
const rand = [];
for (let i = 0; i < 20; i++)
rand.push(Math.floor(Math.random() * 12));
return rand;
}
const App = () => {
const [start, setStart] = useState(true); // 입력 받기 전
const [idx, setIdx] = useState(0); // 현재 위치를 가리키는 인덱스
const [num, setNum] = useState(12); // Container에 전달할 props.num
const rand = useRef(makeRandom());
return (
<>
{
start ?
<div>
N, Count 입력 받기 구현 예정 ㅎㅎ
<button onClick={() => setStart(false)}>게임 시작</button>
</div>
:
<Container num={num}>
<Blocks/>
</Container>
}
</>
)
}
export default App;
import styled from 'styled-components'
export default styled.div`
display: grid;
justify-content: center;
margin-top: 12rem;
grid-template-rows: 150px 150px 150px;
grid-template-columns: 115px 115px 115px 115px;
grid-gap: 5px;
div {
border-style: solid;
border-color: darkblue;
border-width: 1px;
}
#id${props => props.num} {
background: greenyellow;
}
`
div
> 12개.import React from "react";
const Blocks = () => {
return (
<>
<div id={"id0"}> </div> <div id={"id1"}> </div> <div id={"id2"}> </div> <div id={"id3"}> </div>
<div id={"id4"}> </div> <div id={"id5"}> </div> <div id={"id6"}> </div> <div id={"id7"}> </div>
<div id={"id8"}> </div> <div id={"id9"}> </div> <div id={"id10"}> </div> <div id={"id11"}> </div>
</>
)
}
export default Blocks
일정 시간 및 횟수 만큼 동일한 로직이 반복되기 때문에 setInterval을 생각했다.
예시)
3초 후 특정 위치 표시 -> 1초 후 사라짐 -> 2초 후 다시 특정 위치 표시 ...
const App = () => {
(...)
// 시작 버튼을 눌렀을 때 게임 시작~
const handleOnClick = () => {
setStart(false);
const interval = setInterval(() => {
setNum(rand.current[idx]);
console.log(rand.current[idx] + " 켜기");
setTimeout(() => {
setNum(12);
setIdx(idx => idx + 1);
console.log("위치 표시 끄기");
}, 1000)
if (idx === 5)
clearInterval(interval);
}, 3000)
}
(...)
버튼을 클릭하고 3초 후, 위치가 표시된다. 그리고 1초 뒤에 표시가 꺼진다.
하지만 같은 위치만 표시됐다 꺼지고 당연히 clearInterval 또한 되지 않았다.
-> 즉, setInterval 안에서의 state 들은 초기값으로 뱅뱅 돌고 있던 것...
몇 시간을 헤멨는지,,
인덱스 state를 선언하지 않고 인터벌 횟수를 카운트하는 변수를 가지고 고쳐봤다.
일단 작동은 잘 되는데 좋은 방법은 아닌 느낌...
...
// 시작 버튼을 눌렀을 때 게임 시작~
const handleOnClick = () => {
setStart(false);
let intervalCnt = 0;
const interval = setInterval(() => {
setNum(rand.current[intervalCnt]);
console.log(rand.current[intervalCnt] + " 켜기");
setTimeout(() => {
setNum(12);
intervalCnt++;
console.log("위치 표시 끄기");
}, 1000)
if (intervalCnt === 5) {
clearInterval(interval);
console.log("인터벌 종료")
}
},3000)
}
...
집에와서 useRef를 사용해 idx 변수를 선언해서 돌려봤다. 그리고 잘 돌아가는 것을 확인.
아까 했을 땐 왜 안 됐던건지 모르겠다...왜그랬을까...
...
const idx = useRef(0);
const handleOnClick = () => {
setStart(false);
const interval = setInterval(() => {
setNum(rand.current[idx.current]);
console.log(rand.current[idx.current] + " 켜기");
setFlag(true);
setTimeout(() => {
setNum(12);
console.log("위치 표시 끄기");
setFlag(false);
idx.current++;
}, 1000)
if (idx.current === 5) {
clearInterval(interval);
console.log(" 인터벌 종료")
}
},3000)
}
...
토이 프로젝트인 만큼 규모도 크지 않기 때문에 먼저 기능 구현에 집중할 것이다.
완성 후에 리팩토링을 시도할 생각.
학습 목적이기 때문에 이렇게 난관에 부딪히는게 오히려 좋다고 본다 ㅎㅎ
다음 주제는 사용자 입력을 처리하는 로직을 구현하기~