본문 바로가기

React/공식문서(구버전)

[리액트 공식문서] 주요 개념 1 ~ 4 정리

1. Hello React

- React는 사용자 인터페이스(User Interface)를 만들기 위한 JavaScript 라이브러리이다.

- 선언형: 어떤 로직으로 어떻게 코드를 짜야 페이지가 그려질 수 있을까 생각하는 것보다 < 컴포넌트나 데이터 등의 배치를 통해 무엇이 렌더링 될지 생각하는 것이 선언형 UI 핵심이다.

2. JSX

- JavaScript 를 확장한 문법이다.

- React element 를 생성한다.

 

const element = <h1>Hello, World!</h1>

 

- 위에 희한한 태그 문법은 문자열도, HTML도 아닌 JSX 문법이다.

1) JSX에 표현식 포함하기

- JSX의 중괄호 안에는 유효한 모든 JavaScript 표현식을 넣을 수 있다.

- 유효한 JavaScript 표현식에는 2 + 2, user.firstName, formatName(user) 등이 있다.

 

const name = "HANA";
const element = <h1>Hello, {name}</h1>;

2) JSX 속성 정의

- attribute에 따옴표를 이용해 문자열 리터럴을 정의할 수 있다.

- 중괄호를 사용해 attribute에 JavaScript 표현식을 삽입할 수도 있다.

 

const element1 = <a href="https://www.naver.com">네이버</a>;

const element2 = <img src={user.avataUrl} />;
const element3 = <img src="{user.avataUrl}" />; // 이렇게 쓰면 안 됨!

3) JSX로 자식 정의

- JSX 태그는 아래와 같이 자식을 포함할 수 있다.

 

const element = (
  <div>
    <h2>Hello~</h2>
    <h3>Good to see you here!</h3>
  </div>
);

4) JSX는 객체를 표현한다.

- Babel(트랜스 컴파일러)은 JSX를 React.createElement( ) 호출로 컴파일 한다.

- 아래와 같은 JSX 표현식은

 

const element = (
  <h1 className="greeting">
    Hello, World!
  </h1>
)

 

- 아래와 같이 React.createElement( ) 로 호출로 컴파일하고 (즉, 위와 아래 예시는 동일하다)

 

const element = React.createElement(
  "h1",
  {className: "greeting"},
  "Hello, World!"
);

 

- 다음과 같은 객체를 생성한다.

 

const element = {
  type: "h1",
  props: {
    className: "greeting",
    children: "Hello, world!"
  }
};

 

- 위와 같은 객체를 "React 엘리먼트"라고 한다.

- React는 이 객체를 읽어서, DOM을 구성한다.

3. 엘리먼트 렌더링

- 위와 같이 생성된 객체, 엘리먼트는 React 앱의 가장 작은 단위이다.

- 엘리먼트는 화면에 표시할 내용을 기술한다.

- React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트 한다.

 

⚠️ "엘리먼트"는 "컴포넌트"의 구성요소이다.

 

 

1) DOM에 엘리먼트 렌더링 하기

- 모든 엘리먼트가 들어가는 "루트(root)" DOM 노드를 찾는다.

- 위에서 찾은 DOM 요소를 ReactDOM.createRoot( )에 전달한다.

- root.render( )에 React 엘리먼트를 전달한다.

 

/* index.html */
<div id="root"></div>
/* index.js */
const root = ReactDOM.createRoot(document.getElementById("root"));
const element = <h1>Hello, World!</h1>;
root.render(element);

2) 렌더링 된 엘리먼트 업데이트하기

- React 엘리먼트는 불변객체이다.

- "React 엘리먼트는 불변객체이다"라는 것은 생성된 React 엘리먼트의 자식이나 속성을 변경할 수 없다는 의미이다.

- UI를 업데이트 하려면? 새로운 엘리먼트를 생성하고 이를 root.render( ) 로 전달하는 것 뿐이다.

3) 변경된 부분만 업데이트 하기

- React DOM은 (변경된 해당 엘리먼트와 그 자식 엘리먼트를) vs (이전의 엘리먼트)와 비교하고 DOM을 원하는 상태로 만드는데 필요한 경우에만 DOM을 업데이트한다. 

- 새로운 엘리먼트가 생성됐고 업데이트된 UI가 있다면 React DOM은 내용이 변경된 부분만 업데이트 한다.

4. Components와 Props

- 개념적으로 컴포넌트는 JavaScript 함수와 유사하다. "props"라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다.

- 컴포넌트를 정의하는 가장 간단한 방법은 JavaScript 함수를 작성하는 것이다.

 

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

 

- 위 Welcome 함수는 데이터를 가진 하나의 "props" 객체 인자를 받은 후 React 엘리먼트를 반환하므로 유효한 React 컴포넌트이다. 

1) 컴포넌트 렌더링

- React 엘리먼트는 아래와 같이 사용자 정의 컴포넌트로도 나타낼 수 있다.

 

const element = <Welcome name="HANA"/>

 

- React가 위와 같이 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX attribute 자식을 해당 컴포넌트에 단일 객체로 전달한다. 이 객체를 "props"라고 한다.

- 위 예제에서 props 객체는 { name: "HANA" } 이다. 

 

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const root = ReactDOM.createRoot(document.getElementById("root"));
const element = <Welcome name="Sara" />;
root.render(element);

 

⚠️ 컴포넌트의 이름은 항상 대문자로 시작한다.

2) 컴포넌트 합성

- 컴포넌트는 자신의 출력에 다른 컴포넌트를 참조할 수 있다.

- 아래 예제에서 App 컴포넌트는 자신의 출력에 Welcome 컴포넌트를 참조한다.

 

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  )
}

3) 컴포넌트 추출

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

 

function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">{props.text}</div>
      <div className="Comment-date">{props.date}</div>
    </div>
  )
}

function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  )
}

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  )
}

4) props는 읽기 전용

- 컴포넌트의 자체 props를 수정해서는 안된다.

- 모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야 한다.

 

- 아래 예시는 순수 함수다. 순수 함수란 입력값을 바꾸려 하지 않고 항상 동일한 입력값에 대해 동일한 결과를 반환한다.

 

function sum(a, b) {
  return a + b;
}

 

- 아래 예시는 자신의 입력값을 변경하기 때문에 순수함수가 아니다.

 

function withdraw(account, amount) {
  account.total -= amount;
}

 

- 다시 한 번 강조하면, 컴포넌트에게 전달된 props는 읽기 전용이며 컴포넌트 안에서 전달 받은 props를 수정해서는 안된다.