PJT 1. TicTacToe Application_1

서버가 React로 HTML을 먼저 만들고, 브라우저는 그 HTML을 받아서 hydrate로 React 앱으로 되살린다


1. 리액트에서 JSX 사용은 의무일까?

1.1 리액트가 화면을 그리는 방식

const myElement = React.createElement('h1', {}, 'I do not use JSX!')
ReactDOM.render(myElement, document.getElementById('root'))

이걸 JSX로 바꿔보면

<h1>I do not use JSX!</h1>

React의 진짜 본체는 JSX가 아니라 createElement

React.createElement(태그, 속성, 내용)

즉 React의 내부는 전부

JS  객체  Virtual DOM  실제 DOM

🧐 Q. createElement로 UI를 직접 만들면 무슨 일이 벌어질까?

<div className="app">
  <h1>Hello</h1>
  <p>Welcome</p>
</div>

JSX없이 순수 createElement로 쓰면

React.createElement(
  'div',
  { className: 'app' },
  React.createElement('h1', null, 'Hello'),
  React.createElement('p', null, 'Welcome')
)

“모든 요소를 다 createElement API를 사용하면 너무 복잡해진다”

JSX는 “React를 위한 가짜 HTML”이다

<h1>Hello</h1>

⬇️ Babel 변환

React.createElement('h1', null, 'Hello')

JSX (사람이 쓰기 쉬운 문법)
        │
        ▼  Babel
React.createElement(...) (React가 이해하는 진짜 코드)
        │
        ▼
Virtual DOM 객체 생성
        │
        ▼
실제 DOM 렌더링



2. Tic-Tac-Toe 앱 구조 설명

📁 2.1 전체 폴더 구조

react-tictactoe-app/
├── build/          # 빌드된 프로덕션 파일
├── node_modules/   # npm 의존성 패키지
├── public/         # 정적 파일 (HTML, 아이콘 등)
├── src/            # 소스 코드 (메인 개발 폴더)
   ├── components/ # React 컴포넌트
      ├── Board.js / Board.css
      └── Square.js / Square.css
   ├── App.js / App.css
   └── index.js
└── package.json


🧩 2.2 컴포넌트 계층 구조

index.js (진입점)
  └── App.js (메인 컴포넌트 - 게임 로직 관리)
        └── Board.js (3x3 게임판 렌더링)
              └── Square.js (개별  버튼)


📄 2.3 주요 파일별 역할

1. src/index.js - 앱 진입점

  • React 앱을 DOM에 마운트하는 엔트리 포인트
  • React.StrictMode로 앱을 감싸 개발 시 잠재적 문제를 감지

2. src/App.js - 메인 게임 로직

function App() {

  const [history, setHistory] = useState([{ squares: Array(9).fill(null) }]);
  const [xIsNext, setXIsNext] = useState(true);
  const [stepNumber, setStepNumber] = useState(0);
  // ... 게임 로직
}

3가지 상태(State) 관리:

Photo of datatype

Three State Management Patterns

JayTak

주요 함수:

  • calculateWinner(): 8가지 승리 조건을 체크하여 승자 판별
  • handleClick(): 칸 클릭 시 X/O 배치 및 히스토리 업데이트
  • jumpTo(): 과거 수로 돌아가기 (타임 트래블 기능)

3. src/components/Board.js - 게임판 컴포넌트

const Board = ({squares, onClick}) => {

    const renderSquare = (i) => {
        return <Square value={squares[i]}
            onClick={() => onClick(i)} />
    }

    return (
        <div className='board-wrapper'>
            <div className='board-row'>
                {renderSquare(0)}
                {renderSquare(1)}
                {renderSquare(2)}
            </div>
            // ... 3x3 그리드 렌더링
        </div>
    )
}
  • 3x3 그리드 형태로 9개의 Square 컴포넌트를 렌더링
  • squares 배열과 onClick 핸들러를 props로 받음

4. src/components/Square.js - 개별 칸 컴포넌트

const Square = ({ onClick, value }) => {
    return (
        <button className="square"
            onClick={onClick}>
            {value}
        </button>
    )
}
  • 가장 작은 단위의 컴포넌트 (버튼)
  • value (X, O, null)와 onClick 이벤트를 props로 받음



3. 데이터 흐름

전형적인 단방향 데이터 흐름을 따르는 React 앱 구조입니다! 🚀


Photo of datatype

Data Stream Diagram

JayTak