All Articles

ReactJS 기본1

ReactJS 번역 및 정리한 내용. 언어 기능이 생겨 현재는 일부 한글로 번역되어 있는 상태이다. 사내 발표용으로 작성하였다.

  • Hello World
  • JSX 소개
  • Element 렌더링

1. Hello World

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);

2. JSX

const element = <h1>Hello, world!</h1>;
  • 문자열도 HTML도 아니다.
  • UI를 표현

Why JSX

  • ReactJs는 렌더링 로직과 UI로직이 결합되어 있다는 사실을 수용한다.
  • UI로직 : 이벤트 처리 방법, 시간 경과에 따른 상태 변경 방법, 데이터 표시방법이 복합적으로 결합됭 ㅓ있음.
  • 별도의 파일로 마크업과 로직을 분리하는 대신, 이를 포함하는 Component를 통해 관심사를 분리.
  • 꼭 JSX를 사용해야 하는 것은 아니지만 편하기 때문에 많이들 사용한다.

JSX에 표현식 포함하기

이렇게 변수를 포함할 수 있다.

const name = 'Chunghee Park';
/// use const name;
const element = <h1>Hello, {name}</h1>;
);

이렇게 함수의 리턴값을 사용할 수 있다.

function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);
  • 컴파일이 끝나면 JSX는 js 함수 호출이 되고, 객체로 평가 된다.
  • JSX를 if, for 안에서 사용할 수 있고, 변수에 할당하고 파라미터로 함수에서 반환할 수 있다.

JSX로 속성 지정

따옴표로 문자열 속성을 지정할 수 있다.

const element = <div tabIndex="0"></div>;

중괄호로 JS 표현식을 사용하여 변수, 함수의 리턴값 등을 사용할 수 있다.

const element = <img src={user.avatarUrl}></img>;

! 경고

  • JSX는 HTML보다 JS에 가까움
  • ReactDOM은 HTML 속성 이름 대신 camelCase를 사용한다
  • class -> className
  • tabindex -> tabIndex

JSX로 자식 지정

태그가 비어 있으면 바로 닫음

const element = <img src={user.avatarUrl} />;

이렇게 차일드를 포함할 수 있음

const element = (
  <div>
    <h1>Hello!</h1> <!--자식 1 -->
    <h2>Good to see you here.</h2> <!--자식 2 -->
  </div>
);

15까지는 렌더링 할 때 하나의 루트 엘리먼트를 리턴해야함.

<div>
  <PanelA />
  <PanelB />
</div>

16 부터는 이렇게 배열로 렌더링 가능

[
  <li key="one">First item</li>,
  <li key="two">Second item</li>,
  <li key="three">Third item</li>,
  <li key="four">Fourth item</li>,
];

JSX는 주입 공격을 방지한다.

  • 사용자 입력을 JSX에 포함하는것이 안전하다.
  • 기본적으로 ReactDOM은 렌더링 하기전에 JSX에 포함된 모든 값을 escape 처리한다.
  • 따라서 reactjs에서 명시적으로 작성되지 않은 내용은 삽입할 수 있다.
  • 이렇게 하면 XSS(cross-site-scripting) 공격을 회피할 수 있다.
const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;

JSX 객체를 표현

  • 바벨은 JSX를 React.createElementI()를 호출하여 컴파일 한다.
  • 아래 두 예제는 동일하다.
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

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

React.createElement()는 몇 가지 검사를 수행하며 기본적으로 아래와 같은 객체를 생성합니다.

// 주의: 이 구조는 단순화되었습니다.
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};
  • 이런 객체들을 React Elements 라고 부른다.
  • 이런 객체들을 읽고, 이를 바탕으로 DOM을 구성하고 최신 상태로 유지

! Tip
ES6, JSX가 제대로 하이라이트 되도록 하기 위해 Babel 언어 정의를 에디터에 포함해서 사용하는것을 추천한다.


Rendering Elements

Elements는 React app에서 가장 작은 빌드 단위이다

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

const element = <h1>Hello, world</h1>;
  • 브라우저의 DOM element와 달리 React element는 일반 객체 이므로 값 싸게 만들 수 있다.
  • React DOM은 DOM을 React elements와 일치시키도록 신중히 업데이트 한다.

! 주의
더 널리 알려진 개념인 컴퍼넌트와 엘리먼트를 혼동할 수 있다. 엘리먼트는 컴퍼넌트의 구성 요소이다.

DOM에 엘리먼트 렌더링하기

아래와 같이 div가 되어 있다고 가정해보자.

<div id="root"></div>
  • 이것을 루트 DOM 노드라고 부른다. 이 내부에 모든 것이 React DOM에 의해 관리된다.
  • React로 구축 된 애플리케이션은 대개 단일 루트 DOM 노드를 가지고 있다.
  • React를 기존 앱에 통합하는 경우 원하는만큼 많은 수의 분리된 루트 DOM 노드가 있을 수 있다.
  • React 엘리먼트를 루트 DOM 노드로 렌더링 하려면 ReactDOM.render()를 호출한다.
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));

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

  • React Element는 불변이다.
  • 요소를 만든 후에는 해당 Element나 child를 변경할 수 없다.
  • 지금까지 소개한 내용을 바탕으로 하면, UI를 업데이트하는 유일한 방법은 새로운 엘리먼트를 생성하고, 이를 ReactDOM.render()로 전달하는 것이다.

예제로 매초 렌더링 되는 시계를 만들어보겠습니다.

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);

매 초마다 tick을 호출해서 UI 트리 전체를 업데이트 했지만, 변경된 텍스트 노드만 ReactDOM에 의해 업데이트 된다.

! 주의
실제로 대부분의 React 앱은 ReactDOM.render()를 한 번만 호출한다. 다음장에서 상태가 있는 컴퍼넌트가 어떻게 캡슐화 되는지 설명한다.