본문 바로가기
Web/React.js

[STUDY] 리액트의 기본 개념

by 폴우정킴 2020. 9. 8.

1. ReactDOM

 

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

 

 

ReactDOM 은 DOM 상호작용을 하는 메소드들을 모아놓은 패키지 입니다. 주로 리액트 엘리먼트의 삽입이나 업데이트와 관련이 있습니다.

 

render()

리액트와 DOM이 가장 처음 상호작용을 하는 메소드.

 

사용자가 직접 <Calculator/> 라는 리액트 엘리먼트를 정의했다고 했을때,

컨테이너로 작용 할 엘리먼트가 ID 값 container라면 다음과 같은 예시로 사용자 정의 리액트 엘리먼트를 컨테이너안에서 렌더링 할 수 있습니다.

 

ReactDOM.render(<Calculator/>, document.querySelector("#container"));

 

NOTE: 만약 <Calculator/> 사용자 리액트 엘리먼트가 이미 div 엘리먼트에 마운트가 되어 있을때 다시 한번 호출을 하게 된다면 전과 후의 DOM 을 비교해서 업데이트를 하게 됩니다.

위에서 생성한 코드는 결과값으로 참조값을 반환합니다.

 

만약 함수형 컴포넌트를 사용한다면 null을 반환합니다.

NOTE: render함수의 리턴값은 legacy 로 정의됩니다. component를 비동기 적으로 render을 하는 미래의 버전에서는 사용되지 않을 수 있습니다.

 

render() 파라미터

ReactDOM.render(element, container, callback)

 

ReactDOM.render() 메소드는 최대 3개의 값을 파라미터로 받습니다.

  1. element : 렌더링 할 JSX 표현식 or React Element
  2. container : element를 자식으로 받아 렌더링을 시켜 줄 대상
  3. callback : (optional) 렌더링 완료 후 실행 될 콜백 함수

 

Tree Structure

리액트 엘리먼트는 tree structure로 정의됩니다. 즉 각각의 엘리먼트들은 어떠한 React element의 자식이라는 뜻입니다. 하지만 root element HTML코드로 만든 컨테이너 element 안에 만들어 주어야 합니다.

 

위의 다이어그램을 보면 <Calculator /> 가 root React element 라는 것을 확인할 수 있습니다. 그리고 이것은 HTML code 인 div를 container 삼아 렌더링 되었습니다

 

위의 다이어그램을 코드로 보면 이렇습니다.

 

function Calculator() {
  return (
    <>
      <Display />
      <KeyPad />
    </>
  );
}

function KeyPad() {
  return (
    <>
      <NumKeys />
      <FunctionalKeys />
      <Operators />
    </>
  );
}

 

 

참고 자료


2. JSX

 

const element = <h1>Hello, world!</h1>;

 

위 코드의 태그 문법은 문자열도, HTML아닌 JavaScript를 확장한 JSX 라는 문법입니다.

 

JSX 특징

  • JSX는 내부적으로 React.createElement() 함수를 사용합니다.
  • JavaScript 코드 안에서 UI 관련 작업을 할 때 시각적으로 도움이 될 수 있기에 사용합니다.
  • JSX의 중괄호 안에는 유효한 모든 JavaScript 표현식을 넣을 수 있습니다.
  • 컴파일이 끝나면 JSX 표현식은 정규 JavaScript 함수 호출이 되고 JavaScript 객체로 인식됩니다.
  • 즉, JSX를 if 구문 및 for loop 안에 사용하고, 변수에 할당하고, 인자로서 받아들이고, 함수로부터 반환할 수 있습니다.
function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

 

NOTE : JSX는 HTML보다는 JavaScript에 가깝기 때문에, React DOM은 HTML 어트리뷰트 이름 대신 camelCase 프로퍼티 명명 규칙을 사용합니다. 예를 들어, JSX에서 class는 [className] 이 되고 tabindex는 [tabIndex] 가 됩니다.

 

Babel 은 JSX를 React.createElement() 호출로 컴파일 합니다. 다음 두 예시는 동일합니다.

 

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

 

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

which eventually becomes ...

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

 

기본적으로 React DOM은 JSX에 삽입된 모든 값을 렌더링하기 전이스케이프 하므로,

애플리케이션에서 명시적으로 작성되지 않은 내용은 주입되지 않습니다. 모든 항목은 렌더링 되기 전에 문자열로 변환됩니다.

이런 특성으로 인해 XSS (cross-site-scripting) 공격을 방지할 수 있습니다.

NOTE이스케이프란?

특정 문자를 HTML로 변환하는 행위

 

리액트의 이스케이프

React 메뉴얼의 "Dangerously Set innerHTML" 페이지에 따르면, React에서는 cross-site scripting(CSS) 공격을 막기 위해 렌더링 메소드 내부에서 html 태그가 담겨있는 string 형태를 렌더링 하면 태그가 안먹히고 문자열 그대로 렌더링 하게 된다 합니다.

 

render() {
  let codes = "<b>Will This Work?</b>";
    return (
      <div>
          {codes}
      </div>
    );
  }

/*
result is ...
<b>Will This Work?</b>
*/

 

만약 저 문자열에 태그가 적용된 상태로 렌더링이 된다면 스크립트 공격을 할 수 있는 취약점이 생깁니다.

React 에서는 이 취약점을 원천 하단하기 위해 무조건 텍스트 형태로만 렌더링 하게 설정 되어있습니다.

만약 그럼에도 불구하고 태그를 적용하고 싶다면

 

render() {
  let codes = "<b>Will This Work?</b>";
    return (
      <div dangerouslySetInnerHTML={ {__html: codes} }>
      </div>
    );
  }
};

/*
result is ...

Will This Work?
*/

 

dangerouslySetInnerHTML 라는 속성을 사용하면 됩니다.

 

참고 자료


3. Element Rendering

 

<div id="root"></div>

 

HTML 파일 어딘가에 id 값이 root 인 <div> 태그가 있다고 가정한다면 이 안에 들어가는 모든 엘리먼트를 ReactDOM에서 관리하기 때문에 이것을 root DOM Node 라고 부릅니다.

 

React Element 는 불변객체 입니다. 엘리먼트를 생성한 이후에는 해당 엘리먼트의 자식이나 속성을 변경 할 수 없습니다.

NOTE: 불변객체의 장점은?

불변 객체는 하나의 상태만을 갖고 있으므로, 데이터를 신뢰할 수 있다. ( mutable 객체는 메모리 주소를 참조하기 때문에 값을 변경했을 경우 해당 값을 사용하고 있는 모든 곳에서 side effect (부수 효과, 부작용)이 발생하여 예상치 못한 버그를 유발할 수 있습니다. 하지만 immutable 은 객체의 메모리 주소가 불변하기 때문에 내부적으로 구조를 유지할 있고 side effect를 감소시킬 수 있습니다. )Thread-Safe 하므로 멀티 스레드 환경에서 안전하게 사용할 수 있다. (멀티스레드 환경에서)

 

변경된 부부만 업데이트 하기

ReactDOM은 해당 엘리먼트와 그 자식 엘리먼트를 이전의 엘리먼트와 비교하고

DOM을 원하는 상태로 만드는데 필요한 경우에만 DOM을 업데이트 합니다.

 

NOTE: Real DOM 과 가상 DOM의 비교. Reconciliation phase, Commit phase 를 거친다

 

참고 자료


4. Components and Props

사용자 정의 컴포넌트

React 엘리먼트는 사용자 정의 컴포넌트로도 나타낼 수 있습니다.

 

const element = <Welcome name="Paul" />;

 

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

 

사용자 정의 컴포넌트의 이름은 항상 대문자로 시작합니다.


 

'Web > React.js' 카테고리의 다른 글

[STUDY] 컨텍스트  (0) 2021.03.13
[STUDY] 에러 경계  (0) 2021.03.12
[STUDY] 코드분할  (0) 2021.03.10
[STUDY] 접근성  (0) 2021.03.09
Virtual DOM 을 왜 빠르다고 하는가  (0) 2020.06.11

댓글