[TIL #40] React v18 부터 등장한 새로운 hooks

JMinkyoung·2022년 5월 29일
0

TIL

목록 보기
40/42
post-thumbnail


React의 새로운 버전인 18버전은 사실 release 된지는 두달정도 되었지만 (3월 29일에 release 됨) 유튜브 알고리즘을 타고 여기저기 흘러다니던 중,
한 영상을 보고 '오.. 새로운 hook이 추가되었구나.. 뭔지 찾아나 볼까' 하고 관련 문서를 찾아봤고 그중 몇가지만 골라서 이렇게 포스트로 정리하게 되었다.

useTransition

const [isPending, startTransition] = useTransition();

useTransition의 기본적인 사용법은 위와 같다.

React 공식 문서에 적혀있는 설명을 간략하게 설명해보면

useTransition은 일부 state의 업데이트를 미룰수 있게, 즉 급하지 않은 것으로 여기도록 해준다.

예시 코드와 함께 좀더 자세하게 알아보자.

예제

const arr = new Array(10000).fill(0);

export default function App() {
  const [str, setStr] = useState("");
  const [isPending, startTransition] = useTransition();

  const onChangeInput = (e) => {
    setStr(e.target.value);
  };

  return (
    <div className="App">
      <input onChange={onChangeInput}/>
      {
        arr.map(()=> {
          return <div>{str}</div>
        })
      }
    </div>
  );
}

예제 코드를 보면 input을 통해 state를 입력받고 업데이트 하며 해당 state를 10000번 출력하도록 하고 있다.

이런 코드가 있을 때 input을 통해 state를 업데이트 하게 되면 입력을 받을 때 마다 state가 업데이트 되어 10000개의 div가 리렌더링 되기 때문에 엄청난 저하가 발생하게 된다.

  const onChangeInput = (e) => {
    startTransition(() => setStr(e.target.value));
  };

저하를 발생시키는 setState 부분을 startTransition으로 묶어주면 기존의 코드보다는 저하가 덜하다는 것을 확인 할 수 있다.

isPending은 해당 요소가 미뤄지고 있는 지 여부를 boolean 값으로 return 한다.
만약 isPending이 필요 없다면 아래와 같이 startTransition만 불러와서 사용도 가능하다!

import { startTransition } from 'react';

useDeferredValue

const deferredValue = useDeferredValue(value);

useDeferredValue의 기본적인 사용법은 위와 같다.

useDeferredValue은 급하지 않은 트리 부분의 re-rendering 을 연기하는 역할을 한다.

예제

import { useDeferredValue, useState } from "react";

const SlowUI = () => (
  <>
    {Array(50000)
      .fill(1)
      .map((_, index) => (
        <span key={index}>{100000} </span>
      ))}
  </>
);

function App() {
  const [value, setValue] = useState(0);
  const deferredValue = useDeferredValue(value);

  const handleClick = () => {
    setValue(value + 1);
  };

  return (
    <>
      <button onClick={handleClick}>{value}</button>
      <div>DeferredValue: {deferredValue}</div>
      <div>
        <SlowUI />
      </div>
    </>
  );
}

export default App;

버튼을 누르게 되면 일정 시간 지연이 된 후에 (급하지 않은 부분이라고 여겨지고 있기 때문에) 값이 바뀌는 것을 확인 할 수 있다.

useId

const id = useId();

useId의 기본적인 사용법은 위와 같다.

useId는 고유한 id 값을 생성해주는 hook 이다.

웹 개발을 하다보면 element에 고유한 id 값을 지정해줘야 하는 경우들이 있는데 그럴 때 사용 할 수 있는 hook이다.

예제

Child.js

import "./styles.css";
import { useId } from "react";

export default function Child() {
  const id = useId();
  return (
    <div className="child">
      <div>
        <p>child id : {id}</p>
      </div>
    </div>
  );
}

App.js

import "./styles.css";
import { useId } from "react";
import Child from "./Child";

export default function App() {
  const id = useId();
  return (
    <div className="App">
      <div>
        <p>first id : {id}</p>
        <Child />
        <Child />
        <Child />
        <Child />
        <Child />
        <Child />
      </div>
    </div>
  );
}

위와 같은 코드가 있다고 하면 아래와 같이 고유한 id값을 출력하게 된다.

useInsertionEffect

  useInsertionEffect(() => {
  // do something
  });

useInsertionEffect의 기본적인 사용법은 위와 같다.

useInsertionEffect는 css-in-js 라이브러리가 rendering 도중에 스타일을 삽입할 때 발생하는 성능 문제를 해결한다.

예제

import { useEffect, useInsertionEffect, useLayoutEffect } from 'react';

const Child = () => {
  useEffect(() => {
    console.log('useEffect child is called');
  });
  useLayoutEffect(() => {
    console.log('useLayoutEffect child is called');
  });
  useInsertionEffect(() => {
    console.log('useInsertionEffect child is called');
  });
};

function App() {
  useEffect(() => {
    console.log('useEffect app is called');
  });
  useLayoutEffect(() => {
    console.log('useLayoutEffect app is called');
  });
  useInsertionEffect(() => {
    console.log('useInsertionEffect app is called');
  });
  return (
    <div className="App">
      <Child />
      <p>Random Text</p>
    </div>
  );
}

export default App;

위 코드를 통해 실행 순서를 확인 할 수 있는데 그 순서는 다음과 같다.

useInsertionEffect -> useLayoutEffect -> useEffect

이 hook은 사실상 styled-components를 위해서 나왔다 해도 무방하다고 하는데.. 실제로 사용해봐야 정확히 무슨 역할을 하는지 알 수 있을 것 같다.

참고 자료
참고 자료

profile
Frontend Developer

0개의 댓글