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) 관리:
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 앱 구조입니다! 🚀
Data Stream Diagram
JayTak