프론트엔드 개발시 View 구현의 필수 재료인 React 에 대해 공부한다. Nextjs/Gatsby, WebComponent 연계 (1일차)
1. React 공식 문서
React is a JavaScript library for building user interfaces.
- React 는 웹프레임워크가 아니다. UI 전용 라이브러리이다.
- 다른 기술 스택에 대한 제한이 없다. 함께 써라!
- 현재 최신 버전은 v18.2.0 이다.
1) Try React
Online Playgrounds - Hello World template
아래 링크를 이용해 간단히 React 를 프로그래밍 해 볼 수 있다.
2) HTML 에 React 붙이기 - 1분 완성
기존 HTML 에 React CDN 을 추가하고, JS 파일로 React 컴포넌트를 붙일 수 있다.
- 기존 HTML 에 React 라이브러리와 컴포넌트 JS 추가
- react 와 react-dom 필요
1
2
3
4
5
6
7
8
9
10
<!-- ... existing HTML ... -->
<div id="like_button_container"></div>
<!-- ... existing HTML ... -->
<!-- Note: 배포할 때는 "development.js" 대신에 "production.min.js" 을 사용할 것. -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<!-- 추가할 React 컴포넌트 (혹은 외부 컴포넌트) -->
<script src="like_button.js"></script>
- 추가할 컴포넌트 JS (클래스 형식으로 정의된 컴포넌트)
- 버튼이 추가되고, 클릭시 “You liked this.” 문장이 나타남
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'use strict';
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = { liked: false };
}
render() {
if (this.state.liked) {
return 'You liked this.';
}
// React.createElement 생성
return e(
'button',
{ onClick: () => this.setState({ liked: true }) },
'Like'
);
}
}
3) React CLI create-react-app
활용
create-react-app global 삭제
항상 최신 버전을 사용하고 싶다면 global 설치를 하지 말것!
- npx 가 알아서 최신 버전을 찾아 설치한다.
1
2
3
4
5
6
7
$ npm uninstall -g create-react-app
# 또는 yarn global remove create-react-app
$ npx create-react-app my-app
Need to install the following packages:
create-react-app@5.0.1
Ok to proceed? (y)
create-react-app 으로 새 프로젝트 생성
1
2
3
4
5
6
7
8
# npx 로 프로젝트 생성
npx create-react-app hello-react
# 또는 yarn 으로 생성
yarn create react-app hello-react
cd hello-react
yarn && yarn run start
- react, react-dom 필수 라이브러리 설치
- react-script 설치 =>
create-react-app
- web-vitals 설치 : 크롬 브라우져 자동 launch
- index.js 에
reportWebVitals();
추가
- index.js 에
4) Next.js, Gatsby 에서 사용한다
React 는 단지 View 를 전문적으로 다루는 라이브러리임을 잊지 말자.
Next.js
,Gatsby
는 정적, 서버 렌더링 프레임워크- React 를 사용하여 페이지를 생성한다.
- Routing 방식은 각기 다르다.
- Gatsby 는 Jekyll 처럼 파일 경로와 이름에 매칭
2. React Tutorial : Square Board Game (TicTacTok)
보드게임 튜토리얼을 Functional Component(함수형 컴포넌트)로 구현
- 공식문서에는 클래스형 컴포넌트로 설명하고 있음
- 깃허브 또는 검색 결과에는 Board 컴포넌트가 클래스형으로 기술된 것들뿐
- 소스 : 깃허브/react-square-board-game
1) 파일 구성
board-game
- package.json
- public
- index.html :
<div id="root"></div>
포함 - favicon.ico 등.. assets 파일들
- index.html :
- src
- index.js :
#root
에 ReactDOM 생성 (건드릴 부분 없음) - index.css : 전체에 영향을 미치는 스타일 정의
- App.js : root 컴포넌트
- App.css : root 컴포넌트를 위한 스타일 정의
- Game.js : v2 에서 사용되는 게임 상태 클래스를 정의
- index.js :
2) 컴포넌트 구성
App (Game) 컴포넌트
- 보드의 상태 정보를 생성하고 관리
- 현재 상태 또는 종료시 승리자를 출력
Board 컴포넌트
- 플레이어의 클릭 이벤트와 차례를 제어
- 이미 마킹된 경우 변경 없음
Square 컴포넌트
- 최초 상태는 공백
- 클릭된 경우 마킹된 표식을 출력 (X 또는 O)
3) 로직
전체 흐름
- 최초 X 플레이어부터 시작 (다음은 O 플레이어)
- 9개의 셀에 중에 임의의 위치를 클릭하여 자신의 표식을 마킹
- 이미 마킹된 셀의 표식은 변경할 수 없음
- 9개의 셀이 모두 마킹되면, 승리자를 계산
- 승리자를 게임 정보에 출력
Winner 판정 : checkWinner 함수
승리하는 모든 경우의 조합 8가지에 대해, 동일한 player 마킹이 있는지 확인
3) 구현 버전
버전1) Board 에 게임 상태가 저장되는 형태
함수형 컴포넌트가 제각각 출력할 항목과 상태를 관리하는 형태
게임의 상태값과 변경 로직이 흩어져 있는 형태. 헷갈린다.
- Board 의 상태값으로 Square 마킹 출력
- Board 에서 onClick 함수로 게임의 상태 변경을 처리
- App 에서는 info 출력만 관리
버전2) Game 클래스에 게임 상태가 저장되는 형태
흩어진 상태값과 로직을 모두 모아서 Game 클래스로 구성
리액트 컴포넌트는 렌더링에만 집중하도록 하여 코드가 단순해졌다.
- Game Class 에서 모든 상태값을 관리
- Game 인스턴스는 index.js 에서 생성하고 App 컴포넌트에 전달
- App 에서는 Game 의 상태 변경(handleClick)에 대한 로직만 처리
- Board 는 Square 의 위치 바인딩과 함수 전달자 역활만 수행
- onClick 함수의 파라미터 i 값을 바인딩
버전3) History 이용해 이전 스텝으로 이동하는 기능 추가
스텝 버튼 생성을 위한 문자열은 컴포넌트 내에서 생성해야 함
- Game 클래스에서 label 문자열을 만들어 태그를 생성하는데 실패
- 렌더링 되는 대상은 컴포넌트에서 생성되도록 하는게 옳다
- key 를 부여해도
li
가 최종 label 하나만 생성됨
- key 를 부여해도
4) 핵심 포인트
React Without JSX
확장명을 JSX 로 설정할 필요가 없다. JS 가 더 편리해졌음.
1
2
3
4
5
6
7
// index.js
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App game={new Game()} />
</React.StrictMode>
);
함수형 컴포넌트 스타일
- 클래스형 컴포넌트보다 코드가 적어지고 단순해진다.
- 대신 Hook 함수를 적절히 잘 써야함
- 함수형 컴포넌트의 파라미터는
props
로 묶어서 처리하기도 한다.
useState
- 변수와 변경함수가 셋트로 정의된다.
- 컴포넌트가 useState 를 사용하면, 변경에 대한 관리도 컴포넌트 내부에서 해야 함
useEffect
- useEffect 는 두번식 호출되는 경우가 잦다. (마운트, 언마운트)
- 이 Hook 함수로 누적 카운팅 같은 작업은 하지 말것!
9. Review
- React 는 정말 렌더링만 처리한다.
- DOM 계층이 깊어지거나 복잡해지면 데이터와 로직 관리가 어려울듯
- 상태관리 라이브러리가 필수!
- Recoil 을 공부해보자!
- 아직도 밝히지 못한 신비로움이 있다. 분발하자.
끝! 읽어주셔서 감사합니다.