제로초님 영상 보고 따라 만들어본 리액트 로또 추첨기 컴포넌트!
리액트보다 자바스크립트 문법이 더 어렵게 느껴졌다. ㅠㅠ
특히 getWinNumbers 함수 안에 작성된 코드를 좀 더 살펴보고 혼자 만들어보는 시간을 가져봐야겠다!
/* Lotto.js */
import React, { Component } from 'react';
import Ball from './Ball';
function getWinNumbers() {
console.log('getWinNumbers');
const candiate = Array(45)
.fill()
.map((v, i) => i + 1);
const shuffle = [];
while (candiate.length > 0) {
shuffle.push(candiate.splice(Math.floor(Math.random() * candiate.length), 1)[0]);
}
const bonusNumber = shuffle[shuffle.length - 1];
const winNumbers = shuffle.slice(0, 6).sort((p, c) => p - c);
return [...winNumbers, bonusNumber];
}
class Lotto extends Component {
state = {
winNumbers: getWinNumbers(),
winBalls: [],
bonus: null,
redo: false,
};
timeouts = [];
onClickRedo = () => {
this.setState({
winNumbers: getWinNumbers(),
winBalls: [],
bonus: null,
redo: false,
});
this.timeouts = [];
};
runTimeouts = () => {
const { winNumbers } = this.state;
for (let i = 0; i < winNumbers.length - 1; i++) {
this.timeouts[i] = setTimeout(() => {
this.setState((prevState) => {
return { winBalls: [...prevState.winBalls, winNumbers[i]] };
});
}, (i + 1) * 1000);
}
this.timeouts[6] = setTimeout(() => {
this.setState({
bonus: winNumbers[6],
redo: true,
});
}, 7000);
};
componentDidMount() {
this.runTimeouts();
}
componentDidUpdate(prevProps, prevState) {
if (this.state.winBalls.length === 0) {
this.runTimeouts();
}
}
componentWillUnmount() {
this.timeouts.forEach((t) => {
clearTimeout(t);
});
}
render() {
const { winBalls, bonus, redo } = this.state;
return (
<>
<div>당첨 숫자</div>
<div id="result">
{winBalls.map((v) => (
<Ball key={v} number={v} />
))}
</div>
<div>보너스!</div>
{bonus && <Ball number={bonus} />}
{redo && <button onClick={this.onClickRedo}>한번 더!</button>}
</>
);
}
}
export default Lotto;
/* Ball.jsx */
import React, { memo } from 'react';
const Ball = memo(({ number }) => {
let background, color;
if (number <= 10) {
background = 'red';
} else if (number <= 20) {
background = 'orange';
} else if (number <= 30) {
background = 'yellow';
} else if (number <= 40) {
background = 'blue';
color = 'white';
} else {
background = 'green';
}
return (
<div className="ball" style={{ background, color }}>
{number}
</div>
);
});
export default Ball;
1초마다 랜덤으로 뽑은 숫자볼 한개씩 보여주도록 하는 간단한 웹 게임이다.
마지막 보너스 숫자볼을 보여줄 때 '한번 더' 버튼이 나타나서 다시 숫자볼을 뽑아볼 수도 있다.
function getWinNumbers() {
console.log('getWinNumbers');
const candiate = Array(45)
.fill()
.map((v, i) => i + 1);
const shuffle = [];
while (candiate.length > 0) {
shuffle.push(candiate.splice(Math.floor(Math.random() * candiate.length), 1)[0]);
}
const bonusNumber = shuffle[shuffle.length - 1];
const winNumbers = shuffle.slice(0, 6).sort((p, c) => p - c);
return [...winNumbers, bonusNumber];
}
여러 배열 내장 함수를 혼용해서 사용하는 체이닝 방식으로 작성되어서 어려웠기 때문에 이 부분을 중점적으로 보고 다시 만들어봐야겠다.
참고 자료
로또 추첨기 컴포넌트