개발/react

[React] 3-6 숫자야구 만들기

s2somang 2022. 3. 3. 23:53
인프런에 제로초님의 강의를 보고 정리한 내용입니다. 
[ 웹 게임을 만들며 배우는 React ]
https://www.inflearn.com/course/web-game-react

 

리액트에서는 배열에 값을 추가할때 push()를 사용하면 안된다.

=> 리액트에서 무엇이 바뀌었는지 감지하지 못하기때문! 

const arr = [];
arr.push(1);
console.log(arr === arr); //ture
const new_arr = [...arr, 2];
console.log(arr === new_arr) //false

기존 배열을 복사해 만든 새 배열을 할당해주는 방법으로 배열을 갱신해야함!

 

 

리액트에서의 반복문은 대부분 map을 사용함!!

render() {
    const {}
        return (
        <>
        ...
        <ul>
        {this.state.tries.map((v, i) => {return(<Try key={i} tryInfo={v}/>)})}
        </ul>
        </>
    )}
}

{this.state.tries..} 같이 state속성을 사용할때 구조분해문법으로 state속성을 {변수}에 대입하면 this.state를 생략할 수 있음!! 

=> {tries.map .. }

 

클래스 버전

NumberBaseball.jxs 

import { Component ,createRef} from "react";
import Try from "./Try";

// this를 사용하지 않는 경우엔 클래스 밖으로 뺄 수 있음!
const getNumbers = () => {
  // 숫자 네개를 곂치지 않고 랜덤하게 뽑는 함수
  const candidate = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  const array = [];
  for (let i = 0; i < 4; i++) {
    const chosen = candidate.splice(
      Math.floor(Math.random() * (9 - i)), 1)[0];
    array.push(chosen);
  };
  return array;
};

/** class  */
// 바뀌는 부분을 잘 생각해서 component를 만든다.
class NumberBaseball extends Component {
  state = {
    result: "",
    value: "",
    // 화면에 보이지는 않지만 해주어야할 것
    // 숫자 4개를뽑아야함
    answer: getNumbers(), // ex [1,3,5,7]
    tries: [],
  };
 
  onSubmitForm = (e) => {
    e.preventDefault();
    if (answer.join("") === value) {
      this.setState((prevState) => {
        return {
          result: "홈런!",
          tries: [
            ...tries,
            { try: value, result: "홈런!" },
          ],
          value: "",
        };
      });
      alert("홈런!");
      alert("게임 재시작");
      this.setState({
        result: "",
        value: "",
        answer: getNumbers(),
        tries: [],
      });
    } else {
      const answerArray = value.split("").map((e) => parseInt(e));
      let strike = 0;
      let ball = 0;
      if (tries.length >= 9) {
        this.setState({
          result: `실패! 정답은 ${answerArray.join("")}입니다.`,
        });
        alert("게임 재시작");
        this.setState({
          result: "",
          value: "",
          answer: getNumbers(),
          tries: [],
        });
      } else {
        for (let i = 0; i < 4; i++) {
          if (answerArray[i] === answer[i]) strike++;
          else if (answer.includes(answerArray[i])) ball++;
        }
        this.setState((prevState) => {
          return {
            result: `${strike}스크라이크 ${ball}볼`,
            tries: [
              ...tries,
              {
                try: value,
                result: `${strike}스크라이크 ${ball}볼`,
              },
            ],
            value: "",
          };
        });
      }
      this.inputRef.current.focus();
    }
  };

  onChangeInput = (e) => {
    console.log(anwser);
    this.setState({
      value: e.target.value,
    });
  };

  inputRef = createRef();

  render() {
    const { tries, value } = 
    return (
      <>
        <h1>숫자야구</h1>
        <form onSubmit={this.onSubmitForm}>
          <input
            ref={this.inputRef}
            maxLength={4}
            value={value}
            onChange={this.onChangeInput}
          />
        </form>
        <div>시도 : {tries.length}</div>
        <ul>
          {tries.map((v, i) => {
            return (<Try key={i} tryInfo={v} />)
          })}
        </ul>
      </>
    );
  }
}

 

try.js

import React, {PureComponent} from 'react';

class Try extends PureComponent {

render() {
const { tryInfo } = this.props;
return (
	<li>
		<div>{tryInfo.try}</div>
		<div>{tryInfo.result}</div>
	</li>
		)
	}
}

export default Try;