[React] Hello World 안내서 정리 (1/2)

전체내용 : Hello World - React

1. JSX

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

위의 태그문법은 문자열, HTML이 아니다. Javascript를 확장한 문법인 **JSX**이다.
<> ~ </> 부분

1) 특징

  • JavaScript의 모든 기능 포함
  • UI생김새를 설명하기 위해 React와 함께 사용 권장
  • React element를 생성함
  • 컴파일 후, JSX 표션식이 정규 JS함수 호출이 되고, JS객체로 인식됨
  • camelCase 프로퍼티 명명 규칙 사용
  • JSX의 중괄호{} 안에는 모든 유효한 JavaScript 표현식을 넣을 수 있음
    ex) name, 2+2, getName(user) , ...

cf) React

React에서는 이벤트가 처리되는 방식, 시간에 따라 state가 변하느 방식, 화면에 표시하기 위해 데이터가 준비되는 방식 등 렌더링 로직이 본질적으로 다른 UI로직과 연결된다는 사실을 받아들인다.

기본적으로 React DOM은 JSX에 삽입된 모든 값을 렌더링하기 전에 이스케이프 한다. 모든 항목은 렌더링 되기 전에 문자열로 변환된다. (→ XSS(cross-site-scripting) 공격 방지 가능)

2) 객체표현

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

위 두 코드는 같은 결과 (객체생성 → React 엘리먼트)



2. 엘리먼트 (Element) 렌더링

1) 엘리먼트

const element = <h1>이것이 엘리먼트다.</h1>;
  • React 앱의 가장 작은 단위
  • 엘리먼트는 화면에 표시할 내용 기술한다.
  • 특정 시점의 UI (영화에서의 하나의 프레임과 비슷)
  • 일반 객체 (Plain object). 쉽게 생성 가능
  • React DOM은 React엘리먼트와 일치하도록 DOM업데이트
  • 엘리먼트는 컴포넌트의 구성요소

2) DOM에 엘리먼트 렌더링

HTML 파일 어딘가에 있는 <div>

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

이 안에 들어가는 모든 엘리먼트를 React DOM에서 관리함 ⇒ 루트DOM노드 라고 부른다.

  • React로 구현된 애플리케이션은 보통 하나의 루트DOM노드가 있다. (여러 개의 독립된 루트DOM노드가 있을 수도)
  • React 엘리먼트를 루트DOM노드에 렌더링 하려면, 둘 다 ReactDOM.render( ) 로 전달

    const element = <h1>Hello</h1>;
    ReactDOM.render(element, document.getElementByID('root'));



3) 렌더링 된 엘리먼트 업데이트

React 엘리먼트는 불변객체이다. (생성이후에는 자식, 속성을 변경할 수 없음) 오직 특정 시점의 UI를 보여준다. 따라서, 여기까지 기준으로 UI를 업데이트하기 위해서는 새로운 엘리먼트를 생성하고, ReactDOM.render()로 전달하는 방법 뿐!

실제로 대부분의 React앱은 ReactDOM.render()를 한 번만 호출한다.


4) 변경된 부분만 업데이트

React DOM는 DOM을 원하는 상태로 만드는데 필요한 경우에만(ex. 변화가 생긴) DOM을 업데이트한다.

3. Components and Props

1) 컴포넌트

  • UI를 재사용 가능한 개별적인 여러 조각으로 나누고, 각 조각을 개별적으로 살펴볼 수 있다.
  • 개념적으로 JavaScript의 함수와 유사함
  • props(속성을 나타내는 데이터) 라는 객체 인자를 받아 React 엘리먼트로 반환
  • 컴포넌트의 이름은 항상 대문자로 시작한다.

컴포넌트를 정의하는 아래의 두 가지 방법은 동일하다.
1. JavaScript함수로 정의하는 방법

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

"함수 컴포넌트"라고 호칭함

2. ES6 class를 사용하여 정의하는 방법

class Welcome extends React.Component {
	render() {
		return <h1>Hello, {this.props.name}</h1>;
 }
}



(1) 컴포넌트 렌더링

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

const element = <Welcome name="Sara" />;
// 여기서 props -> {name: 'Sara'}

React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX어트리뷰트와 자식을 해당 컴포넌트(여기서는 Welcome)에 단일 객체로 전달한다. 이 객체를 "props"라고 한다.
이때, props의 이름은 사용될 context가 아닌 컴포넌트 자체의 관점에서 짓는 것을 권장한다. (ex. name이라는 props 이름은 Welcome 컴포넌트의 관점!)

(2) 컴포넌트 합성

  • 컴포넌트는 자신의 출력에 다른 컴포넌트를 참조할 수 있다.
  • 일반적으로 새 React 앱은 최상위에 단일 App 컴포넌트를 갖고 있다.

(3) 컴포넌트 추출

  • 컴포넌트를 여러 개의 작은 컴포넌트로 나누기
  • 구성요소들을 모두 중첩하는 구조보다, 몇 가지 컴포넌트로 나누는 것을 추천한다.
    (컴포넌트를 변경하고 구성요소들을 재사용하기 편해진다.)

2) Props는 읽기 전용

  • 컴포넌트에서는 자체 props를 수정해서는 안 된다!!
  • 모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야 한다.

    순수함수 : 입력값을 바꾸지 않고, 항상 동일한 입력값에 대해 동일한 결과를 반환하는 함수



4. State와 생명주기

props와 유사하지만, 비공개이며 컴포넌트에 의해 완전히 제어된다.

1) 클래스 컴포넌트로 state를 사용할 수 있다.

ES6 class로 컴포넌트를 사용한다.
render메서드는 업데이트가 발생할 때마다 호출되지만, 같은 DOM노드로 해당 클래스(ex. <Clock />)를 렌더링하는 경우, 그 클래스의 단일 인스턴스만 사용된다.
이를 통해 로컬 state, 생명주기 메서드 등과 같은 부가적인 기능을 사용할 수 있다.

사용방법

  1. 클래스로 컴포넌트를 작성한다.
  2. 생성자 추가 ( props 전달 방식 집중! )

    constructor(props) {
        super(props);
        this.state = {date: new Date()};
      }

    클래스 컴포넌트는 항상 props로 기본 constructor를 호출해야 한다.

  3. this.props 대신 this.state 사용
  4. props를 삭제한다. <Welcome name="Sara" /><Welcome />

2) 생명주기메서드 추가하기

생명주기 메서드를 이용해서 컴포넌트가 마운트되거나 언마운트 될 때 일부 코드를 작동할 수 있다.

  • componentDidMount() 컴포넌트 출력물이 DOM에 렌더링 된 후에 실행된다.
  • componentWillUnmount()
  • this.setState() 컴포넌트 로컬 state 업데이트

사용방법 예시

다음 링크의 예시 참고 Hello World in React

  1. <Clock />ReactDOM.render()로 전달되었을 때 React가 Clock 컴포넌트의 constructor을 호출한다.
  2. Clock컴포넌트의 render() 메서드 호출 → React는 화면에 표시될 내용을 알게 됨 → DOM 업데이트
  3. Clock출력값이 DOM에 삽입되면 componentDidMount() 메서드 호출 → 이 안에서 매초 tick() 메서드르를 호출하기 위한 타이머를 설정하도록 브라우저에 요청
  4. 매초 브라우저가 tick() 메서드 호출함. → 이 안에서 setState()에 현재 시각을 포함하는 객체를 호출하면서 UI 업데이트 → React는 state가 변경된 것을 인지 (setState()덕분) → 화면에 표시될 내용을 알아내기 위해 render() 다시 호출 → 이 때 render() 안의 this.state.date가 달라짐. → 렌더링 출력값은 업데이트된 시각을 포함 → React는 이것을 따라 DOM업데이트
  5. Clock 컴포넌트가 DOM으로부터 삭제되면 componentWillUnmount() 메서드 호출 (타이머를 멈추기 위해)

3) State를 올바르게 사용하기

  1. State를 직접 수정하는 대신 setState() 사용한다. this.state를 지정할 수 있는 유일한 공간은 constructor
  2. state업데이트는 비동기적일 수 있다. 이때 발생하는 업데이트 실패 문제를 해결하기 위해 setState((state, props) ⇒ ( <내용> ); 사용
  3. state의 독립적인 변수들은 별도의 setState() 호출로 독립적으로 업데이트 할 수 있다.

4) 기타 특징

  • 컴포넌트는 자신의 state를 자식 컴포넌트에 props로 전달할 수 있다.
© 2020 euzl. from JunhoBaik's, Built with Gatsby