react 고급개념

서동수·2022년 7월 25일
0

코드 분할

번들링은 React앱을 하나의 병합된 파일로 만들어 한번에
전체 앱을 로드할 수 있게한다.

그렇지만 앱이 커지면 번들도 커지게되며 로드시간이 길어지게된다.
이것을 방지하는게 코드 분할이며 런타임에 번들을 동적으로 만들고 불러오는 것으로 번들러들이 지원하는 기능이다.

이를 통해 성능 향상을 기대할 수 있고 앱의 코드는 줄지 않은 상태에서 사용자가 필요하지 않은 코드를 불러오지 않아 앱의 초기화 로딩에 대한 비용을 줄여준다.

(Suspense, lazy, dynamic import, Route)

Context
공식문서: https://ko.reactjs.org/docs/context.html

context의 주된 용도는 다양한 레벨에 네스팅된 많은 컴포넌트에게 데이터를 전달하는 것으로
context를 사용하면 컴포넌트를 재사용하기가 어려워지므로 꼭 필요할 때만 쓰는 것이 좋다.

Ref

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// 이제 DOM 버튼으로 ref를 작접 받을 수 있습니다.
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

Fragment

여러개의 자식 태그, 컴포넌트를 그룹화 할 수 있도록 해준다.
key만 유일하게 전달가능 한 어트리뷰트 이다.

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // React는 `key`가 없으면 key warning을 발생합니다.
        <React.Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </React.Fragment>
      ))}
    </dl>
  );
}

// key가 없다면 아래와 같이 표현할 수 있다.
<>
	<dt>{item.term}</dt>
	<dd>{item.description}</dd>
</>

HOC

컴포넌트 로직을 재사용하기 위한 패턴으로
컴포넌트를 Prop으로 받아 새로운 컴포넌트를 반환하는 구조이다.

예를들어 비슷한 로직에 사용하는 데이터만 다르다면

컨테이너 컴포넌트(A)에 실제 렌더링할 컴포넌트(B)와 데이터를 받아
A가 반환하는 컴포넌트(C)에서 데이터를 가지고 로직을 수행하고
컴포넌트(B)에 Props로 전달하여 렌더링을 실시한다.
이렇게 하면 데이터만 변경하면 로직의 재사용이 가능한 패턴으로 작성이 가능하다.

결과적으로 입력된 컴포넌트를 수정하지 않고 상속을 사용해 동작을 복사하지도 않으며
원본 컴포넌트를 컨테이너 컴포넌트로 Wrapping하고 Compose(조합)하기 떄문에 사이드 이팩트가 없는
순수함수 이다.

재조정

state나 props가 갱신되며 render() 메소드는 새로운 React엘리먼트를 반환할 것이다.
이때 React는 방금 만들어진 트리에 맞게 효과적으로 UI를 갱신하는 방법을 알아낼 필요가 있다.

리액트에서는 아래 2가지 가정을 통해서 트리임에도 O(n) 복잡도의 휴리스틱 알고리즘을 구현했다.

  1. 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
  2. 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해 줄 수 있다.

루트의 엘리먼트 타입이 다르다면 이전 DOM노드를 버리고 새로운 DOM노드가 삽입된다.
당연하게 루트 엘리먼트 하위 컴포넌트 모두 언마운트되고 state도 사라진다.

DOM 엘리먼트 타입이 같은 경우 속성을 확인해 변경된 속성만 갱신한다.
이 후 노드의 자식들을 재귀적으로 처리한다.

컴포넌트가 갱신되면 state는 유지되고 새로운 엘리먼트를 반영하기위해 props를 갱신하고 비교 알고리즘을 통해
이전과 현재를 재귀적으로 처리한다.

DOM 노드의 자식을 재귀적으로 처리할 때 React는 두 리스트를 순회하고 차이점이 있다면 변경한다.
자식의 끝에 엘리먼트를 추가하면 변경은 잘 작동할 것이다.
가장 앞에 엘리먼트를 추가한다면 모든 자식은 변경될것이며 비효율적으로 동작하게 된다.
이러한 문제를 해결하기위해 key속성을 지원해 key를 통해 비교를 수행하여 효율적이게 된다.

리액트 컴포넌트 , 리액트 엘리먼트

리액트 컴포넌트는 페이지 렌더링에 사용할 리액트 엘리먼트를 반환하는 재사용 가능한 코드 조각
리액트 엘리먼트는 리액트 앱을 구성하는 블록으로 화면에 보이는 것들을 기술하며 변경되지 않습니다.
일반적으로 엘리먼트는 직접 사용되지 않고 컴포넌트로 부터 반환됩니다.

제어 컴포넌트 vs 비제어 컴포넌트

React에 의해 입력값이 제어되는 엘리먼트를 제어 컴포넌트라고 한다.
예를 들어 input의 value를 상태로 하고 onChange를 이용한다면 입력마다 이벤트 핸들러에 의해 코드가 호출되고 렌더링이 이루어지고 입력의 유효성을 결정하며 렌더링이 이루어 지지 않으면 엘리먼트는 변경되지 않은 상태로 유지된다.

비제어 컴포넌트는 React외부에서 작동하는 것처럼 보이는데, 사용자가 데이터를 입력시 업데이트된 정보를 React에서 별도로 처리하지 않고 엘리먼트에 반영한다.

대부분 제어 컴포넌트를 사용해야 한다.

profile
devLog

0개의 댓글