[0629_2] 함배리(함께 배우는 리액트)

장 창영·2021년 7월 6일
post-thumbnail

4. 리액스 공식문서 읽기(1~5)

(!는 sw스터디에서 같이 읽은 내용을 토대로 작성했습니다)

https://reactjs.org
Copyright © 2021 Facebook Inc.

1. Hello World

React는 JavaScript(이하 JS) 라이브러리
= JS 기본적으로 공부하고 오셈
-> React에서 추천하는 링크

2. Introducing JSX

JSX? 자바스크립트를 확장한 문법!
-> React의 Element를 produce(생성)함

2-1. Why JSX?

React는 'rendering logic' is coupled with(연결) 'UI logic'라 생각
-> rendering logic + UI logic = "component"를 사용

2-2. Embedding Expressions in JSX

JSX 안에서 {자바스크립트 표현식} 사용가능

2-3. JSX is an Expression Too

JSX는 컴파일 종료 시, 자바스크립트 함수를 호출하면서 자바스크립트 객체로 인식됨
= JSX도 표현식임

2-4. Specifying Attributes with JSX

attributes(속성)으로 "문자열" or {자바스크립트 표현식} 사용가능!
HTML < JavaScript에 가까움 -> HTML attribute < 'camemlCase' 사용하셈

2-5. Specifying Children with JSX

자식태그 포함가능
<닫는 태그 /> 반드시 필요

2-6. JSX Prevents Injection Attacks

injection attack 방지함
React DOM은 JSX의 삽입된 값을 rendering하기 전에 escape -> never inject anything that’s not explicitly(명시적으로) written
= 모든 항목은 렌더링되기 전에 문자열로 변환
-> XSS 공격 방지
나도 뭔 소린지 모르겠는데, 걍 injection attack을 방지한다는 것만 알면 될 듯

2-7. ! JSX Represents Objects

React.createElement() 호출 -> Babel compiles JSX
-> 대충 Babel이 컴파일해서 돌아간다는 뜻
React.createElement()가 대충 버그검사하고 element 객체 생성
element가 뭐임?

const element = {
  type: 'tag',
  props: {
    key: 'value',
  }
};

화면에서 보고 싶은 것을 나타내는 애
따라서 React는 Element를 읽어서 DOM을 구성하고 최신상태로 유지하는 라이브러리라 보면 될 듯

3. Rendering Elements

Element? 화면에 표시할 내용을 적는 React의 가장 작은 building blocks(대충 단위로 해석하면 될 듯)!
-> React DOM이 React Element와 DOM을 일치하도록 DOM을 업데이트!

React Element는 브라우저 DOM Element와 달리, plain object이며 쉽게 생성가능
Component != Element -> 'Component > Element(Component의 구성요소)'

3-1. Rendering an Element into the DOM

HTML의 태그 안에 Element를 넣어서 rendering
-> React DOM이 Element를 관리하므로, 이를 'DOM node'라고 부름

보통 React 애플리케이션은 하나의 DOM node가 존재
React를 기존 애플리케이션에 통합할 경우, 다양한 DOM node 존재

! 3-2. Updating the Rendered Element

React elements은 immutable(불변)해야 함!
= Element 생성 후, 자식이나 속성을 변경이 안 됨!
그럼 UI를 어케 업데이트함?
새 Element를 생성하고, 이를 ReactDOM.render()로 전달!
대부분의 React app은 ReactDOM.render()를 한 번만 호출

즉, immutable = rendering된 경우, 메모리영역을 다시 건들 수 없음!
-> 그럼 어케 바꿈? 아래에 정답!

3-3. React Only Updates What’s Necessary

React DOM은 해당 Element를 이전의 Element와 비교하고, DOM을 원하는 상태로 만드는데, 필요한 경우에만 DOM을 업데이트함
UI를 어떻게 보여주니? React, "Given moment > Over time"!

즉, 어케 바꿈?
-> 'virtual DOM으로 달라진 부분을 체크해서 고놈만 바꿈 > 전체 페이지를 계속 바꿈'
= React는 가장(x) 충분히(o) 빠르다

4. Components and Props

UI -> independent(개별적인) reusable(재사용 가능한) pieces of 'Components'
Funtions(JavaScript) = Components(React)
props를 입력 -(Components)-> 화면을 보여주는 React Elements를 반환

4-1. Function and Class Components

  1. Function Components
function FunctionComponent(props) {
  return <tag>{props.key}</tag>;
}
  1. Class Components
class ClassComponent extends React.Component {
  render() {
    return <tag>{props.key}</tag>;
  }
}

React의 관점에서 두 가지 Components가 동일

4-2. Rendering a Component

const element = <tag />;
or
const element = <Component key="value" />

React element -> DOM 태그 or 사용자 정의 component

function Component(props) {
  return <tag>{props.key}</tag>;
}

const element = <Component key="value" />;
ReactDOM.render(
  element,
  document.getElementById('id')
);
  1. element를 파라미터로 ReactDOM.render()를 호출
  2. key를 prop으로 전달하여 Component를 호출
  3. Component는 Element(tag)를 return
  4. React DOM은 Component의 return과 일치하도록 DOM을 업데이트

React는
소문자로 시작 -> DOM 태그로 처리
대문자로 시작 -> Component로 처리
= Component는 항상 대문자로 시작

4-3. Composing Components

Component는 출력에 다른 Component를 refer(참조)할 수 있음
-> Component 결합

4-4. Extracting Components

Component -(split)-> smaller Components
App이 커질수록 -> reusable Components 굿굿

Component를 얼마나 나누냐에 따라 rendering 횟수가 달라짐
-> 적절한 extracting 필요

4-5. !Props are Read-Only

Props는 Component가 생성될 때 초기에 받아옴

Component가 절대로 자체 Props를 수정해서는 안 됨!
pure? input을 수정하지 않고, 동일한 input에 동일한 output을 return함

All React component는 반드시 pure function으로 동작해야 함
이는 UI가 동적으로 변하는 것과는 무관하며, state를 통해 이를 위반하지 않고 React Component가 output을 변경할 수 있음

5. state and lifecycle

React Component 안의 state와 lifecycle?

렌더링된 출력값을 변경?
-> 지금까지는 ReactDOM.render() 함수 호출하는 식

Component를 완전히 reusable(재사용) + encapsulated(캡슐화)?
Component에 “state”를 추가!
State는 Props와 유사하지만, private(비공개) + fully controlled by the component(컴포넌트에 의해 완전히 제어)

5-1. Converting a Function to a Class

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function -> class
1. React.Component를 extends한 같은 이름의 ES6 class 생성
2. 빈 render() 메소드 추가
3. function의 body(내용)을 render() 메소드 안으로 이동
4. render 안의 props를 this.props로 변경
5. 함수 삭제

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

render는 업데이트마다 호출되지만, 같은 DOM node로 render하는 경우에는 class의 single instance로만 사용됨
-> local state와 lifecycle methods를 사용할 수 있게 함

5-2 Adding Local State to a Class

props -> state로
1. render() 메소드 안에 있는 this.props.key -> this.state.key
2. 최초의 this.state를 지정하는 class constructor를 생성

constructor(props) {
    super(props);
    this.state = {key: value};
  }

class component는 항상 props로 기본 constructor를 호출
3. element에서 key prop을 삭제

5-3. Adding Lifecycle Methods to a Class

components가 삭제되면 사용 중이던 resources를 확보해야 함!

mount? 처음 DOM에 render될 때마다 타이머를 설정하려고 함
unmount? 생성된 DOM이 삭제될 때마다 타이머를 해제하려고 함

component class에서 특정 메소드를 선언하여 component가 mount되거나 unmount될 때 일부 코드를 작동 -> “lifecycle methods”.

componentDidMount() 메소드는 Component output이 DOM에 rendering된 후에 실행 -> 타이머 설정에 좋음

componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

data flow 안에 포함되지 않는 항목을 보관하고 싶다면, 자유롭게 class에 manually하게 부가적인 field를 추가 가능!

componentWillUnmount() 메소드

  componentWillUnmount() {
    clearInterval(this.timerID);
  }
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

constructor -> render -> did -> willun
1. <Component이름 />가 ReactDOM.render()로 전달될 때, React가 Component의 constructor를 호출 -> this.state를 초기화
2. React는 component의 화면에 표시할 render() 메소드를 호출 -> React는 rendering output을 일치시키기 위해 DOM을 업데이트
3. 출력값이 DOM에 insert되면, React는 componentDidMount() lifecycle method를 호출. 그 안에서 component는 메소드를 호출하기 위한 타이머를 설정하도록 브라우저에 요청.
4. browser가 타이머에 맞춰 메소드를 호출. 그 안에서, component는 setState() 호출로 UI업데이트를 진행. setState() 호출로, React는 state가 변한 걸 인지하고, 화면에 표시될 내용을 알기 위해 render()메소드를 다시 호출. 이 떄 render 메소드 안의 this.state.key가 달라지고, rendering output은 업데이트를 포함. React는 이에 따라 DOM을 업데이트.
5. Component가 DOM으로부터 삭제된다면, React는 멈추기 위해 componentWillUnmount() lifecycle method를 호출

5-4. Using State Correctly

Do Not Modify State Directly
constructor에서 this.state를 assign + setState()
-> this.state.key = value? component를 다시 렌더링하지 않음

State Updates May Be Asynchronous
React는 setState()를 single 업데이트로 한꺼번에 처리 가능
this.props와 this.state가 asynchronous으로 업데이트될 수 있음 -> state를 계산할 때 해당 값에 의존하면 안 됨

this.setState({
  counter: this.state.counter + this.props.increment,
});
->
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
or
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

State Updates are Merged
setState()를 호출할 때, React는 제공한 객체를 현재 state로 merge
this.setState()를 각각 호출하여 independently 업데이트할 수 있음 -> 병합은 shallow하게 이뤄지므로, this.state.key1과 this.state.key2는 각각 업데이트(서로 영향x)

5-5. The Data Flows Down

parent component나 child component 모두 특정 component가 stateful이거나 stateless인지 알 수 없음 + function이거나 class이거나 관심 없음
state = local or encapsulated
component가 소유하고 state가 설정한 component 이외에는 어떠한 component도 접근 불가

component는 자신의 state를 child component에 props로 전달가능
-> state로 왔는지, props로 왔는지, 수동으로 입력한지 알 수 없음
= top down or unidirectional data flow -> 모든 state는 항상 특정 component가 소유하며 그 state로부터 파생된 UI나 data는 tree 구조에서 자신의 below에 있는 component에만 영향

tree = props의 폭포
each component의 state = 특정 지점에서 만나지만 동시에 아래로 흐르는 addtional water source

React apps에서 component가 stateful이거나 stateless인 건 시간의 흐름에 따라 바뀔 수 있는 component의 implementation detail stateful component에서 stateless components 사용 가능. 역도 마찬가지

+a

이게 먼저 떠올라야 함
state(상태) -> 이 컴포넌트(자신)의 상태라서 외부에서 접근이 안 됨.
props 받아옴 + 수정불가
setstate?
직접적으로 바꾸지 마세요 + 동기적으로 안 바뀔 수도 있어요

5. (과제)

5-1. 틱택토 게임

내가 만든 틱택토 보고 가셔유

5-2. React에서 훅이란?

0개의 댓글