From 4207a8a8b9ffada2a11c49affef52aad49347aa8 Mon Sep 17 00:00:00 2001 From: haerong22 Date: Mon, 8 Mar 2021 19:31:15 +0900 Subject: [PATCH] =?UTF-8?q?react=20web=20game=20:=20=EB=A1=9C=EB=98=90?= =?UTF-8?q?=EC=B6=94=EC=B2=A8=EA=B8=B0=20Hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- react_webgame/main/Lotto-class.jsx | 93 +++++++++++++++++++++++ react_webgame/main/Lotto.jsx | 115 +++++++++++++---------------- 2 files changed, 143 insertions(+), 65 deletions(-) create mode 100644 react_webgame/main/Lotto-class.jsx diff --git a/react_webgame/main/Lotto-class.jsx b/react_webgame/main/Lotto-class.jsx new file mode 100644 index 00000000..1db6cb5b --- /dev/null +++ b/react_webgame/main/Lotto-class.jsx @@ -0,0 +1,93 @@ +import React, { Component } from "react"; +import Ball from "./Ball"; + +function getWinNumbers() { + console.log("getWinNumbers"); + const candidate = Array(45) + .fill() + .map((v, i) => i + 1); + const shuffle = []; + while (candidate.length > 0) { + shuffle.push( + candidate.splice(Math.floor(Math.random() * candidate.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 = []; + + runTimeouts = () => { + const { winNumbers } = this.state; + for (let i = 0; i < this.state.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(); + } + + componentWillUnmount() { + this.timeouts.forEach((v) => { + clearTimeout(v); + }); + } + + componentDidUpdate(prevProps, prevState) { + if (this.timeouts.length === 0) { + this.runTimeouts(); + } + } + + onClickRedo = () => { + this.setState({ + winNumbers: getWinNumbers(), + winBalls: [], + bonus: null, + redo: false, + }); + this.timeouts = []; + }; + + render() { + const { winBalls, bonus, redo } = this.state; + return ( + <> +
당첨 숫자
+
+ {winBalls.map((v) => ( + + ))} +
+
보너스
+ {bonus && } + {redo && } + + ); + } +} + +export default Lotto; diff --git a/react_webgame/main/Lotto.jsx b/react_webgame/main/Lotto.jsx index 0fa92ef7..1877e8b6 100644 --- a/react_webgame/main/Lotto.jsx +++ b/react_webgame/main/Lotto.jsx @@ -1,4 +1,10 @@ -import React, { Component } from "react"; +import React, { + useState, + useRef, + useEffect, + useMemo, + useCallback, +} from "react"; import Ball from "./Ball"; function getWinNumbers() { @@ -17,77 +23,56 @@ function getWinNumbers() { return [...winNumbers, bonusNumber]; } -class Lotto extends Component { - state = { - winNumbers: getWinNumbers(), - winBalls: [], - bonus: null, - redo: false, - }; +const Lotto = () => { + const lottoNumbers = useMemo(() => getWinNumbers(), []); + const [winNumbers, setWinNumbers] = useState(lottoNumbers); + const [winBalls, setWinBalls] = useState([]); + const [bonus, setBonus] = useState(null); + const [redo, setRedo] = useState(false); + const timeouts = useRef([]); - timeouts = []; + useEffect(() => { + runTimeouts(); + return () => { + timeouts.current.forEach((v) => { + clearTimeout(v); + }); + }; + }, [timeouts.current]); - runTimeouts = () => { - const { winNumbers } = this.state; - for (let i = 0; i < this.state.winNumbers.length - 1; i++) { - this.timeouts[i] = setTimeout(() => { - this.setState((prevState) => { - return { - winBalls: [...prevState.winBalls, winNumbers[i]], - }; - }); + const runTimeouts = () => { + for (let i = 0; i < winNumbers.length - 1; i++) { + timeouts.current[i] = setTimeout(() => { + setWinBalls((prevBalls) => [...prevBalls, winNumbers[i]]); }, (i + 1) * 1000); } - this.timeouts[6] = setTimeout(() => { - this.setState({ - bonus: winNumbers[6], - redo: true, - }); + timeouts.current[6] = setTimeout(() => { + setBonus(winNumbers[6]); + setRedo(true); }, 7000); }; - componentDidMount() { - this.runTimeouts(); - } + const onClickRedo = useCallback(() => { + setWinNumbers(getWinNumbers()); + setWinBalls([]); + setBonus(null); + setRedo(false); + timeouts.current = []; + }, [winNumbers]); - componentWillUnmount() { - this.timeouts.forEach((v) => { - clearTimeout(v); - }); - } - - componentDidUpdate(prevProps, prevState) { - if (this.state.winBalls.length === 0) { - this.runTimeouts(); - } - } - - onClickRedo = () => { - this.setState({ - winNumbers: getWinNumbers(), - winBalls: [], - bonus: null, - redo: false, - }); - this.timeouts = []; - }; - - render() { - const { winBalls, bonus, redo } = this.state; - return ( - <> -
당첨 숫자
-
- {winBalls.map((v) => ( - - ))} -
-
보너스
- {bonus && } - {redo && } - - ); - } -} + return ( + <> +
당첨 숫자
+
+ {winBalls.map((v) => ( + + ))} +
+
보너스
+ {bonus && } + {redo && } + + ); +}; export default Lotto;