본문 바로가기

React/실험실

[React] React18에서 추가된 Hook

React 18버전에 새롭게 추가된 Hook이 몇가지 있다. 

▶ useId 

useTransition

useDeferredValue

useSyncExternalStore

useInsertionEffect 

 

사실 추가가 되었다고 사용해보지는 않았다. 

( 사용성이 있는지는 의문...! )

 

useId 

유니크한 Id 값을 만들어주는 Hook이다. 

이게 끝이다 ㅋㅋ.... 

 

태그에 id 값을 넣어야 하는 경우 

const passwordField = () => {
  const passwordId = useId();
  
  return (
    <> 
     <input type="password" />
     <p id={passwordId}> ... </p>
    <>
  )
}

다음과 같이 사용할 수 있다. 

이렇게 사용하면 id 가 중복으로 들어가는 경우를 방지할 수 있겠지만, 굳이 사용해야할까? 라는 의문은 있다. 

id 를 고민하는 일이 없다는 장점은 있겠다. 

 

useTransition 

내부에서 사용하는 state 값이 변경되는지를 감지하는 Hook이다. 

const component = () => {
  const [toggle, setToggle] = useState(false);
  const [isPending, startTransition] = useTransition();
  
  const toggleState = () => {
    startTransition(() => {
      setToggle(prev => !prev);
    }
  }
  
  
  useEffect(() => {
    console.log("isPending :", isPending);
  }, [isPending]);
  
  return (
    <button onClick={}>update</button>
  )
}

다음과 같이 사용하면, 최초 상태가 변경되기 전에는 isPending은 false 값을 가지지만

버튼을 클릭해서 상태가 변경되는 순간 isPending은 true가 되고 변경이 완료되면 다시 false가 된다. 

 

useDeferredValue

useTransition이 상태가 변경되는 것을 감지한다면, useDeferredValue는 연속적인 상태 업데이트가 일어나면 

렌더링을 대기했다가 한번에 출력된다. 

 

export default function App() {
  const [text, setText] = useState('');
  const deferredText = useDeferredValue(text);
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <SlowList text={deferredText} />
    </>
  );
}

const SlowList = memo(function SlowList({ text }) {
  console.log('[ARTIFICIALLY SLOW] Rendering 250 <SlowItem />');

  let items = [];
  for (let i = 0; i < 250; i++) {
    items.push(<SlowItem key={i} text={text} />);
  }
  return (
    <ul className="items">
      {items}
    </ul>
  );
});

function SlowItem({ text }) {
  let startTime = performance.now();
  while (performance.now() - startTime < 1) {
    // Do nothing for 1 ms per item to emulate extremely slow code
  }

  return (
    <li className="item">
      Text: {text}
    </li>
  )
}

export default SlowList;

다음 예시는 SlowItem이 250초 이후에 렌더링이 발생한다. 

 

만약 useDeferredValue를 사용하지 않은 경우, 250초 뒤에 value가 렌더링되지만, 

useDeferredValue의 값을 넘겨주면 input의 value인 text는 먼저 업데이트되고 SlowItem이 렌더링된다. 

 

즉, input의 value는 업데이트가 되므로 사용자 측면에서는 성능이 좋아졌다고 볼 수 있다.

 

이것은 글로만 확인하면 이해가 어려울 수 있으므로, 링크를 통해 직접 테스트를 확인하면 느껴질 것이다. 

 

useSyncExternalStore

Store를 구독하는 기능이다. 

쉽게 말해서 redux와 비슷한 기능이라고 보면 된다. store를 구독하였다가 값이 변경을 감지해서 

업데이트를 발생한다. 

 

하지만 굳이 이것을 사용하기 보단, redux를 사용하는게 더 좋지 않나 생각이 든다. 

 

useInsertionEffect 

useLayoutEffect가 동작하기 전 스타일을 먼저 조작하는 Hook이다. 

css 라이브러리를 개발하는 경우가 아니라면 사용하는 경우가 거의 없다. 

반응형