"지속적으로 데이터가 변화하는 대규모 애플리케이션 구축하기"
1. Element
React 앱의 가장 작은 단위, 화면에 표시할 내용을 기술한다.
일반 객체이며(plain object) 쉽게 생성할 수 있다. React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트한다.
const element = <h1>Hello, world</h1>;
React 엘리먼트를 루트 DOM 노드에 렌더링하려면 둘 다 ReactDOM.render()로 전달하면 된다.
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
React 엘리먼트는 사용자 정의 컴포넌트로도 나타낼 수 있습니다.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
2. Component
개념적으로 컴포넌트는 JavaScript 함수와 유사하다.
“props”라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다.
클래스형 컴포넌트와 함수형 컴포넌트로 구별되며, 클래스형 컴포넌트는 render()를 구현해야 한다.
※ 모든 React 컴포넌트는 자신의 props를 다룰 때 수정해서는 안된다.
3. render()
클래스 컴포넌트에서 반드시 구현돼야하는 유일한 메서드. React 엘리먼트 또는 다른 객체를 반환해야 한다.
4. 조화 과정 (reconciliation)
리액트의 뷰를 업데이트하는 과정을 조화 과정이라고 하며, 컴포넌트에서 데이터에 변화가 있을 때 새로운 요소로 갈아끼우는 것. 컴포넌트는 데이터를 업데이트했을 때 단순히 업데이트한 값을 수정하는 것이 아니라, 새로운 데이터를 가지고 render 함수를 다시 수정한다.
이후 render 함수가 반환된 결과값을 이전에 render 함수가 만든 컴포넌트 정보와 비교하여 둘의 차이를 최소한의 연산으로 DOM 트리에 업데이트한다.
5. DOM(Document Object Model)
객체로 문서 구조를 표현하는 방법. 트리 형태로 특정 노드의 탐색, 삭제, 수정, 삽입이 가능.
DOM 자체는 빠르지만 웹 브라우저 단에서 DOM에 변화가 일어나면 CSS를 다시 연산하고 레이아웃을 구성하고 페이지를 리페인트하면서 시간이 허비되게 된다.
6. Virtual DOM
조화 과정을 통해 DOM 업데이트를 추상화함으로써 DOM 처리 횟수를 최소화하고 효율적으로 진행한다.
리액트에서 데이터가 변하면 아래의 세 가지 절차를 밟는다.
1) 데이터를 업데이트하면 전체 UI를 Virtual DOM에 리렌더링합니다.
2) 이전 Virtual DOM에 있던 내용과 현재 내용을 비교합니다.
3) 바뀐 부분만 실제 DOM에 적용합니다.
7. 왜 Node.js를 설치하는가?
프로젝트를 개발하는 데 필요한 주요 도구들이 Node.js를 사용하기 때문
8. JSX
자바스크립트의 확장 문법. 브라우저에서 실행되기 전에 코드가 번들링되는 과정에서 바벨을 사용하여 일반 자바스크립트 형태의 코드로 변환된다. JSX 안에서는 자바스크립트 표현식을 사용할 수 있다.
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
- 삼항 연산자를 통해 if문을 대신한다. (참고로 falsy한 값인 0은 화면에 출력된다)
- 카멜 표기법을 사용한다. (예: background-color → backgroundColor)
- class 대신 className을 사용한다.
- 주석은 /* */
9. ReactDOM.render
컴포넌트를 페이지에 렌더링하는 역할.
지니고 있는 정보들을 사용하여 HTML 마크업을 만들고, 실제 페이지의 DOM 요소 안에 주입한다.
즉, 렌더링 → HTML 마크업 → DOM 주입의 과정이 수행된다.
아래 예시에서는 다음과 같은 일들이 일어납니다.
- <Welcome name="Sara" /> 엘리먼트로 ReactDOM.render()를 호출합니다.
- React는 {name: 'Sara'}를 props로 하여 Welcome 컴포넌트를 호출합니다.
- Welcome 컴포넌트는 결과적으로 <h1>Hello, Sara</h1> 엘리먼트를 반환합니다.
- React DOM은 <h1>Hello, Sara</h1> 엘리먼트와 일치하도록 DOM을 효율적으로 업데이트합니다.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
10. export default (JS)
export default를 사용하면 '해당 모듈엔 개체가 하나만 있다’는 사실을 명확히 나타낼 수 있다.
이렇게 default를 붙여서 모듈을 내보내면 중괄호 {} 없이 모듈을 가져올 수 있다.
// 📁 user.js
export default class User { // export 옆에 'default'를 추가해보았습니다.
constructor(name) {
this.name = name;
}
}
// 📁 main.js
import User from './user.js'; // {User}가 아닌 User로 클래스를 가져왔습니다.
new User('John');
10. props
properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소이다.
props 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정할 수 있다.
11. 비구조화 할당 (ES6)
객체에서 값을 추출하는 문법. 내부 값을 바로 추출하며, 함수의 파라미터 부분에도 사용 가능하다. 파라미터가 객체라면 그 값을 바로 비구조화해서 사용한다.
// 비구조화 할당 미사용
import React from 'react';
const MyComponent = props => {
return (
<div>
{props.name}
</div>
)
}
MyComponent.defaultProps = {
name: 'default'
}
export default MyComponent;
// 비구조화 할당 사용
import React from 'react';
const MyComponent = ({ name }) => {
return (
<div>
{name}
</div>
)
}
MyComponent.defaultProps = {
name: 'default'
}
export default MyComponent;
배열에도 아래와 같이 적용 가능하다.
const array = [1, 2];
const [one, two] = array;
12. state
컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.
- 클래스형 컴포넌트 : state
- 함수형 컴포넌트 : useState라는 함수를 통해 사용
constructor 메서드 또는 state 변수를 통해 직접 초깃값을 선언할 수 있다.
값을 수정할 때에는 this.setState 또는 useState 함수를 꼭 사용해야 하며
두 번째 파라미터에 callback 함수를 추가로 지정할 수 있다.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0
}
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>fixedNumber : {fixedNumber}</h2>
<button
onClick={() => {
this.setState({number: number + 1});
}
}
>+1</button>
</div>
)
}
}
useState 함수는 아래와 같이 사용한다. (첫 번째 원소 : 현재 상태, 두 번째 원소 : 세터)
import { useState } from 'react';
const Say = () => {
const [message, setMessage] = useState('');
const onClickEnter = () => setMessage('Hi!');
const onClickLeave = () => setMessage('good bye!');
return (
<div>
<button onClick={onClickEnter}>Enter</button>
<button onClick={onClickLeave}>Exit</button>
<h1>{message}</h1>
</div>
)
}
export default Say;
※ 객체나 배열과 같은 경우, 사본을 만들어서 그 사본의 상태를 세터를 통해 업데이트한다.
12. 번들링
모듈화된 코드를 한 파일로 합치는 것. 주로 웹팩을 사용하는 것 같다.