JS/React

React - useTransition & useDeferredValue

shin96bc 2024. 3. 9. 17:17

이번에 사용해 볼 기능들은 리액트가 업데이트되고나서 나온 신기능들 입니다.

 

batch 기능 업데이트 사항

원래 batch 기능이란 state 변경 함수가 여러개 모여있을 경우에 state 변경함수마다 재랜더링이 되는게 아니라 맨 마지막 state 변경함수가 실행되고나서 한번만 재랜더링되는 기능을 말합니다.

이 batch 기능이 리액트 18버전 전까지는 ajax, setTimeout 같이 조금 늦게 동작하는 기능들의 내부라면 batch 기능이 작동을 안해서 모든 state 변경함수가 실행될 때마다 재랜더링 되었던게 18버전부터는 state 변경함수가 어디에 있던간에 상관없이 batch 기능이 잘 작동되도록 수정되었습니다.

즉, 이제는 어디에 state 변경함수가 있어도 맨 마지막 state 변경함수가 실행되고 나서 딱 한번만 재랜더링이 일어난다는 의미입니다.

 

useTransition 이라는 훅 추가

useTransition 이라는 훅은 느린 컴포넌트의 성능을 향상시켜주는 기능을 합니다. ( 비유: 카드 빚 돌려막기 )

 

사용법

 

우선 state 하나와 input 태그 하나를 만듭니다.

 

그 다음에 input 태그에 유저가 뭔가를 입력할 때마다 state 에 해당 값을 저장하도록 합니다.

  • App.js

 

그리고 테스트를 위해 일부러 성능저하가 일어나도록 div 태그를 만개정도 생성하도록 코드를 짜봅시다.

  • 먼저 0이 만개정도 채워진 배열을 생성합니다.
  • App.js

 

  • 그 다음에 map 함수를 사용해서 div 태그를 만들어주는 코드를 작성합니다.
  • App.js

 

  • 자 이렇게 코드를 짜놓으면 키보드를 한번 입력할 때마다 만개의 div 태그를 만들기 때문에 성능이 많이 저하될겁니다. 이렇게 키보드 조작후에 몇초씩 걸리는 사이트는 답답해서 유저들이 다 떠나게 될겁니다.

 

자 이제 이 성능저하 상황을 해결해봅시다.

  • 먼저 성능이 저하되는 코드를 지우는 방법이 있겠습니다만, 만약 해당코드가 꼭 필요한 코드라면 지울 수 없을겁니다.
  • 그럴때 18버전부터 추가된 useTransition 기능을 사용해서 해결해봅시다.
  • 먼저 import 를 해줍니다.
  • App.js

 

  • useTransition 에는 유용한 데이터 두개가 Array 자료로 들어가 있습니다. 이 데이터 두개를 아래와 같이 꺼내서 사용합니다. ( 보통 아래와같은 변수명을 사용합니다. )
  • App.js

 

  • 두번째에 있는 데이터 startTransition 이라는 이름의 데이터는 함수입니다. 이 함수로 성능저하를 일으키는 state 변경 작업들을 감싸주시면 됩니다. ( 이렇게하면 조금 성능이 향상되는 것을 볼 수 있습니다. )
  • App.js

 

  • 첫번째에 있는 변수 isPending 은 startTransition 이 아직 처리중일 때  true 로 변하는 변수입니다. 그래서 아래처럼 startTransition 가 실행중이면 로딩중이라는 글자를 보여주는 등의 작업이 가능해집니다.

 

startTransition 의 동작 원리

  • 먼저 왜 div 태그 10000개를 생성할 때 성능이 저하되었는지 부터 알아야합니다.
  • 브라우저는 기본적으로 single-threaded 로 되어있어서 동시작업을 못하고, 한번에 하나의 작업만 할 수 있기 때문에 성능이 저하되는 것입니다.
  • 그래서 startTransition 함수가 하는 일은 코드의 시작을 뒤로 늦춰주는 것입니다. startTransition 이라는 함수안에 작성한 코드는 다른 중요한 작업을 먼저 처리하고나서 처리가 됩니다.
  • 이렇게 실행시점을 조금 다르게 해줘서 성능을 향상시키는게 startTransition 의 동작원리입니다.

 

useDeferredValue 라는 함수 추가

useDeferredValue 도 useTransition 과 똑같이 성능을 향상시켜주는 기능입니다.

 

사용법

 

사용법은 조금 다릅니다. 먼저 import 를 해줍니다.

 

그 다음에 useDeferredValue 함수에 파라미터에는 state 혹은 props 를 넣을 수 있도록 되어있습니다.

그래서 파라미터에 state 나 props 를 넣게되면 변경된 state 나 props 를 새로운 변수로 return 해줍니다.

 

useDeferredValue 에 넣어준 state 혹은 props 는 변동사항이 생기면 조금 늦게 처리해줍니다. 그리고 그 변화된 값을 return 해줍니다.

 

이렇게해도 useTransition 과 비슷하게 동작합니다.