React 복습 - 숫자 야구 게임

Stella·2025년 8월 25일

React

목록 보기
3/7

사용자 인터페이스(UI)를 만들기 위한 JavaScript 라이브러리 -> 개발자의 자유도가 높다.

리액트를 사용하는 이유

Vanilla JS : 순수하게 자바스크립트만을 이용해 개발한 것

Markup : HTML 언어로 정적인 화면을 구성하는 것
HTML = HyperText Markup Language
Rendering : 웹 브라우저에서 읽어들인 웹 문서(HTML, CSS, JS)를 웹 표준에 맞도록, 화면에 적절히 그려내는 것

React의 특징 : 선언형, 명령형, 컴포넌트 기반, 한 번 배워서 어디서나 사용하기

  • Virtual DOM과 DOM
    DOM(Document Object Model) : 문서 객체 모델 html문서를 제어하기 위한 인터페이스 문서 내의 요소를 정의하고, 각 요소의 접근하는 방법을 제공

Virtual DOM : 리액트에서 좀 더 효율적인 화면 렌더링을 위해 구성된 기술 패턴
요소 단위의 수정을 반영하는게 아닌 변화를 감지하고 한번에 DOM에 수정된 사항을 적용

  • Virtual DOM과 리액트
    리액트는 State 기반 렌더링, State가 바뀌면 Virtual DOM이 수정되고 Virtual DOM은 DOM과 비교하면서 변경된 부분을 반영

CRA를 이용해서 작업 환경을 구축한다.
create react app

숫자 야구 프로젝트?

Transpiler : Babel
어떠한 언어로 작성된 코드를 같은 수준의 다른 코드로 변환하는 작업
JSX => JavaScript, TypeScript => JavaScript

사람이 읽고 이해할 수 있는 수준의 언어 레벨

컴파일 Compile : 개발자가 작성한 고급 언어(C, Java)를 기계가 이해할 수 있는 기계어(저급 언어)로 변환하는 과정
C언어 => 어셈블리어, 기계어

트랜스파일 Transpile :
어떠한 언어로 작성된 코드를 같은 수준의 다른 코드로 변환하는 작업
JavaScript ES5 => JavaScript ES6

Why JSX? : JSX의 코드가 깔끔하고 직관적으로 읽기 편하다.

useState

useEffect

개발자도구에서 확인할 수 있도록 서버와 통신, 내부 변경할 때 사용한다.
특수한 경우 콜백함수가 실행된다.

const [randomNumber] = useState(generateRandomNumber())
useEffect(() => {
	console.log(randomNumber)
}, []) 두번째 인자는 배열로 받는다.

빈 배열을 넣어 1회만 실행하도록 한다.

사용자 입력 받기

import './App.css';
import { useEffect, useState } from 'react';
import { generateRandomNumber } from './random'

export default function App() {
  //console.log(generateRandomNumber());
  const [randomNumber] = useState(generateRandomNumber())
  const [answer, setAnswer] = useState('');

  useEffect(() => {
    console.log(randomNumber);
    
  },[randomNumber])

  // const handleAnswerChanged = (e) => {
  //   console.log(e.target.value);
  //   setAnswer(e.target.value)
  // }

  const handleAnswerChanged = (e) => {
    console.log(e.target.value)
    setAnswer(e.target.value)
    
  }

  const handleSubmit = () => {
    // 스트라이크, 볼, 정답 유무
    const answers = answer.split('').map(item => Number(item)); // 분리된다.

    // 각자의 수를 비교한다.
    const {strike, ball} = randomNumber.reduce((prev, cur, index) => {
      // 같은 자리에 같은 수가 존재하면 스트라이크
      if(answers[index] === cur){
        return {
          ...prev, // 기본값이 들어간다.
          strike: prev.strike + 1
        }
      }
      // 다른 자리에 수가 존재하면 볼
      if(answers.includes(cur)){
        return {
          ...prev,
          ball: prev.ball + 1
        }
      }
      return prev;
    },{
      // reduce 기본값
      strike: 0,
      ball: 0
    } )
    
    console.log('strike', strike, 'ball', ball);
    
    
  }

  return (
    <div className="App">
      <header className='header'>{randomNumber}</header>
      <section>
        <input type='text' value={answer} onChange={handleAnswerChanged} />

        <button onClick={handleSubmit}>맞춰보기</button>
      </section>
      <h2>기록</h2>
      <ol>
        <li>1234 (strike: 0, ball: 2)</li>
        <li>5678 (strike: 1, ball: 1)</li>
        <li>7895 (strike: 1, ball: 1)</li>
      </ol>
    </div>
  );
}

기록 남기기 기능 개발

const [logs, setLogs]=useState([]); // 기본값으로 배열을 선언

if(strike === 4) {
	setLogs([...logs, `${answer} 축하합니다. 정답입니다.`])
    return;
}
setLogs([...logs, `${answer} Strike: ${strike}, Ball: ${ball}`])
<h2>기록</h2>
<ol>
	{
    	logs.map((log, index) => {
        	return (
            	<li key{`${log} ${index}`>{log}</li>
            )
  		})
   	}
</ol>

새로운 게임 시작 기능

유효성 검사 기능 개발

잘못되지 않게 하는 방어 로직이다.
1) 문자를 입력했을 경우 입력 x

2) 숫자 자릿수 까지

함수 컴포넌트

React 엘리먼트를 반환하는 javascript 함수 형태의 컴포넌트

함수 컴포넌트는 Props라는 객체 인자를 넘겨 받을 수 있다.
ex) input 태그의 type, value, onChange, disabled가 담긴 객체가 Props이다.

클래스 컴포넌트

자주 쓰이지 않는다. 코드가 길어진다. 다른 컴포넌트에서 재사용하기 어렵다.

  • 클래스 컴포넌트

잘 사용하지 않는다. 그냥 알고 넘어가기!

profile
공부 기록

0개의 댓글