- React
JSX 문법 - 주사위 게임, 가위바위보, state 활용
나둥식
2022. 11. 15. 23:43
1️⃣ 주사위 던지는 기능 만들기 - useState() + set함수로 변경
① Button.js 컴포넌트
function Button({ children, onClick }) {
return <button onClick={onClick}>{children}</button>;
}
export default Button;
② App.js에 useState 함수 사용하기
import "./App.css";
import Dice from "./Dice";
import Button from "./Button";
import { useState } from "react";
function random(n) {
return Math.ceil(Math.random() * n);
}
function App() {
const [num, setNum] = useState(1);
const handleRollClick = () => {
const nextNum = random(6);
setNum(nextNum);
};
const handleClearClick = () => {
setNum(1);
};
return (
<>
<div>
<Button onClick={handleRollClick}>던지기</Button>
<Button onClick={handleClearClick}>처음부터</Button>
</div>
<Dice color="red" num={num} />
</>
);
}
export default App;
- 던지기(handleRollClick)을 클릭하면 setNum 함수를 랜덤으로 호출함
- 처음부터(handleClearClick)를 클릭하면 setNum 함수가 1을 호출함
- const nextNum = random(6); : 숫자를 6으로 고정하고 6까지 랜덤으로 nextNum을 setNum함수로 상태값 변경
🔎 Math.ceil()
: 입력받은 숫자보다 크거나 같은 정수 중 가장 작은 정수를 리턴함 = 입력받은 숫자를 올림한 정수를 리턴
🔎 Math.random()
: 0보다 크거나 같고 1보다 작은 무작위 숫자를 반환함 (실수로 반환)
➡ return Math.ceil(Math.random() * n); : Math.random()이 무작위 숫자를 실수로 반환하므로 Math.ceil을 사용하여 올림을 해주어야 함
2️⃣ 가위바위보 패 고르는 기능 만들기
① Button.js
function Button({ children, onClick }) {
return <button onClick={onClick}>{children}</button>;
}
export default Button;
② HandIcon.js
import rock from "./assets/rock.svg";
import scissor from "./assets/scissor.svg";
import paper from "./assets/paper.svg";
const IMAGES = {
rock: rock,
scissor: scissor,
paper: paper,
};
function HandIcon({ value }) {
const src = IMAGES[value];
return (
<>
<img src={src} alt={value} />
</>
);
}
export default HandIcon;
③ HandButton.js
import HandIcon from "./HandIcon";
function HandButton({ value, onClick }) {
const handleClick = () => onClick(value);
return (
<button onClick={handleClick}>
<HandIcon value={value} />
</button>
);
}
export default HandButton;
④ Utils.js
const HANDS = ['rock', 'scissor', 'paper'];
const WINS = {
rock: 'scissor',
scissor: 'paper',
paper: 'rock',
};
export function compareHand(a, b) {
if (WINS[a] === b) return 1;
if (WINS[b] === a) return -1;
return 0;
}
function random(n) {
return Math.floor(Math.random() * n);
}
export function generateRandomHand() {
const idx = random(HANDS.length);
return HANDS[idx];
}
🔎 Math.floor()
: 인수로 전달받은 값과 같거나 작은 수 중에서 가장 큰 정수를 반환함
⑤ App.js
import "./App.css";
import HandIcon from "./HandIcon";
import Dice from "./Dice";
import HandButton from "./HandButton";
import Button from "./Button";
import { useState } from "react";
import { generateRandomHand, compareHand } from "./utils";
function getResult(me, other) {
const comparison = compareHand(me, other);
if (comparison > 0) return "승리";
if (comparison < 0) return "패배";
return "무승부";
}
function App() {
const [hand, setHand] = useState("rock");
const [otherHand, setOtherHand] = useState("scissor");
const handleButtonClick = (nextHand) => {
const nextOtherHand = generateRandomHand();
setHand(nextHand);
setOtherHand(nextOtherHand);
};
const INIT_VALUE = "rock";
const handleClearClick = () => {
setHand(INIT_VALUE);
setOtherHand(INIT_VALUE);
};
return (
<div>
<Button onClick={handleClearClick}>처음부터</Button>
<p>{getResult(hand, otherHand)}</p>
<div>
<HandIcon value={hand} />
VS
<HandIcon value={otherHand} />
</div>
<div>
<HandButton value="rock" onClick={handleButtonClick} />
<HandButton value="scissor" onClick={handleButtonClick} />
<HandButton value="paper" onClick={handleButtonClick} />
</div>
</div>
);
}
export default App;
- 버튼(handleButtonClick)을 클릭하면
- HandButton 컴포넌트의 handleClick이 실행됨
- handleClick 함수에서는 onClick 함수를 value값으로 실행함
- 이 때, onClick 함수는 상위 컴포넌트인 App에서 prop(nextHand)으로 내려준 handleButtonClick 함수이다.
- 즉, handleButtonClick(value)가 실행되는 것!
⑥ 실행결과