본문 바로가기

이것저것 스터디📚/React - 공식 문서

React 공식문서 -useInsertionEffect

- useInsertionEffect는 CSS-in-JS 라이브러리 작성자를 위한 훅이다. CSS-in-JS 라이브러리에서 작업중에 스타일을 주입하는 경우가 아니라면 useEffect나 useLayoutEffect가 더 나을 수 있다.

- useInsertionEffect는 useEffect의 버전 중 하나로, DOM 변이 전에 실행된다.

- 즉, useInsertionEffect를 호출하여 DOM 변이 전에 스타일을 주입한다.

Usage(사용법)

Injecting dynamic styles from CSS-in-JS libraries(CSS-in-JS 라이브러리에서 동적 스타일 삽입하기)

- CSS-in-JS에는 세 가지 일반적인 접근 방식이 있다.

1. 컴파일러를 사용하여 CSS 파일로 정적 추출

2. 인라인 스타일 (예: <div style={{opacity : 1}}>

3. 런타임에 <style> 태그 삽입

 

- 이때, 런타입에 <style> 태그 주입은 다음 두 가지 이유로 권장하지 않는다.

1. 런타임 주입은 브라우저에서 스타일을 훨씬 더 자주 계산하도록 한다.

2. 런타임 주입이 React 라이프사이클에서 잘못된 시점에 발생하면 속도가 매우 느려질 수 있다.

 

- useInsertionEffect를 사용하면 두 번째 문제는 해결할 수 있다.

- 즉, useInsertionEffect를 호출하여 DOM 변경 전에 스타일을 주입한다.

// CSS-in-JS 라이브러리 코드 내부에
let isInserted = new Set();
function useCSS(rule) {
  useInsertionEffect(() => {
    // 앞서 설명한 것처럼 <style> 태그의 런타임 주입은 권장하지 않습니다.
    // 하지만 런타임 주입을 해야한다면, useInsertionEffect에서 수행하는 것이 중요합니다.
    if (!isInserted.has(rule)) {
      isInserted.add(rule);
      document.head.appendChild(getStyleForRule(rule));
    }
  });
  return rule;
}

function Button() {
  const className = useCSS('...');
  return <div className={className} />;
}

- useInsertionEffect는 useEffect와 마찬가지로 서버에서 실행되지 않는다.

- 따라서, 어떤 CSS 규칙이 사용되었는지 수집해야 하는 경우 서버 렌더링 중에 수집할 수 있다.

let collectedRulesSet = new Set();

function useCSS(rule) {
  if (typeof window === 'undefined') {
    collectedRulesSet.add(rule);
  }
  useInsertionEffect(() => {
    // ...
  });
  return rule;
}

* 참고 : React 공식문서(https://react-ko.dev/learn)