[Worksheet 220516] React 공식문서 고급 - Composition, HOC, Memoization

방예서·2022년 5월 16일
0

Worksheet

목록 보기
35/47
React 공식문서로 디테일 잡기(고급)

Composition

Composition은 합성으로 어떤 컴포넌트 안에 컴포넌트를 넣는 것이다.
두 가지 방법이 있다.

Children props

Children을 사용해서 그대로 가지고 오는 방법이다.

// Dialog.jsx
// 자식을 감싸고 있는, 어떻게 보면 일반적인 컴포넌트
// 스타일을 줄 때 얘한테 전체적인 스타일을 주고, 자식에게는 걔만의 스타일 지정하는 식으로 사용
import React from 'react'

export default function (props) {
  return (
    <div>
      {props.children}
    </div>
  )
}
// WelcomeDialog.jsx
import React from 'react'
import Dialog from './Dialog'

export default function WelcomeDialog() {
  return (
    <Dialog>
      <h1>Welcome!</h1>
      <h5>Thank you~!</h5>
    </Dialog>
  )
}

Custom

특수한 경우 직접 커스텀해서 사용한다.

// CustomDialog.jsx
import React from 'react'

export default function CustomDialog (props) {
  return (
    <div>
      <h1>{props.title}</h1>
      <h5>{props.description}</h5>
    </div>
  )
}
// WelcomeDialog.jsx
import React from 'react'
import CustomDialog from './CustomDialog'

export default function WelcomeDialog() {
  return (
    <CustomDialog title="Welcome" description="thank you!" />
  )
}

Custom 확장

  • typeof
    typeof로 type을 체크하고, 원하는대로 조정한다.

다양한 상황을 품을 수 있도록 composition을 확장하는 것이다.
일반적인, 감싸는 컴포넌트에게 확장성을 주어서 가져다 쓰는 컴포넌트에게 자유도를 주는 것이다.

composition과 inheritance

react는 강력한 합성 모델을 가지고 있으며, 상속 대신 합성(Composition) 을 사용하며 컴포넌트 간에 코드를 재사용하는 것이 좋다!

HOC

고차 컴포넌트. Higher Order Component.
컴포넌트 로직을 재사용하기 위한 고급 기술이다.
컴포넌트를 가지고 와서 새로운 컴포넌트를 반환하는 함수이다.

loading이 true이면 Loading... 을 띄우고 2초 뒤에 버튼을 띄우는 코드이다.
여기서 로딩 부분을 HOC로 만들어 사용하고 싶다.

// Button.jsx
import React, { useEffect, useState } from 'react'

export default function ButtonHoc() {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const timer = setTimeout(() => setLoading(false), 2000)
    return () => clearTimeout(timer);
  }, []);

  return loading ? <p>Loading...</p> : <button>Button</button>
}

withLoading.jsx 라는 파일을 만들어 코드를 그대로 붙여준다.
하지만 파일의 이름이 대문자로 시작하지 않아서 오류가 발생한다.
그렇기 때문에 파일 내에서 컴포넌트를 리턴하도록 한다.

// withLoading.jsx
import React, { Component, useEffect, useState } from 'react'

// 컴포넌트를 받아서 컴포넌트를 반환한다. => HOC
export default function withLoading(Component) {
  const WithLoadingComponent = (props) => {
    const [loading, setLoading] = useState(true);

    useEffect(() => {
      const timer = setTimeout(() => setLoading(false), 2000)
      return () => clearTimeout(timer);
    }, []);
  
    return loading ? <p>Loading...</p> : <Component {...props} />
  };

  return WithLoadingComponent;
}

이렇게 HOC를 만들고, 다시 돌아가 사용해보자.

import withLoading from './withLoading'

function ButtonHoc() {
  return <button>Button</button>
}

export default withLoading(ButtonHoc);

Memoization

컴퓨터 프로그램이 동일한 계산을 반복해야할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다.

memo()

동일한 Props로 렌더링한다면, React.memo를 사용하면 성능 향상이 가능하다.
memo를 사용하면 React는 컴포넌트를 렌더링하지 않고 마지막으로 렌더링된 결과를 재사용한다.
memo는 props의 변화 에만 영향을 준다.

예를 들어 1초마다 하나의 요소가 추가 되는 것을 생각해보자.
memo를 사용하지 않으면 하나가 추가될 때마다 모든 것이 다시 랜더링 된다. 1개, 2개, 3개, ...
memo를 사용하면 이미 그려졌던 요소들은 재사용하기 때문에 1개 추가, 1개 추가, ... 이런식으로 동작한다.

useCallback()

하지만 부모 요소에 핸들러 함수가 추가 되어서 props, 내 자신이 바뀌면 memo를 해도 다 렌더링 된다. 상태가 바뀌면 memo 사용해도 다시 렌더링!
-> 이 때 함수를 memoization 하고 싶으면 useCallback hook 사용한다.

함수를 memoization 하는 hook

useMemo

변수를 memoization 할 수 있는 hook
useMemo를 사용해서 두번째 인자로 특정 값을 주면 그 값은 memoization.

Profiler

react에서 제공하고 있는 성능을 계산할 수 있는 API.
성능 분석 도구.

profile
console.log('bang log');

0개의 댓글