이챙의 개발 log
useTransition으로 성능 개선하기
⭐️useTransition 이란⭐️
상태 변경의 우선순위를 낮춰 다른 렌더링이 더 빠르게 수행되도록 해줄 수 있는 hook 이다. (리액트 18에 생김)
왜?? 이것을 사용해야 할까?
리액트는 기존에 동기적으로 처리 되고 있었다. 즉 하나의 작업에 하나만 처리가 된다는 것인데 리액트가 렌더링이 끝날때까지 순차적으로 계속 지연이 된다는 것이다. useTransition 훅을 통해 동시성을 실현할 수 있다.
동시성을 실현하게 되면 A와 B의 작업을 처리하고 있을시 B를 지연시키고 A를 처리할 수 있다.
코드로 구현해보기
function App() { const data = ['사과','배','오렌지','바나나','딸기','천례향','귤','자몽','수박','키위','아보카도','참외'] const allData = Array(5000).fill([...data]); const [text,setText] = useState('') const handleChange = (e) => { setText(e.target.value) } return ( <div className="App"> <input type="text" onChange={handleChange}/> {text} <SearchBox data={allData} text={text}/> </div> ); } export default App;

위의 코드는 인풋에 과일 이름 입력시 5000개의 data에서 사용자가 입력한 인풋과 동일하면 해당 데이터의 컬러가 바뀌도록 하는 코드이다. 데이터가 5000개 정도를 렌더링하게 되면 굉장히 버벅거리게 될것이다. 왜냐하면 렌더링 하는데 시간이 소요되기 때문이다.
input과 SearchBox는 text라는 상태를 서로 공유하고 있기 때문에 input의 값이 바뀔때마다 SearchBox도 같이 렌더링 되기 때문에 버벅거리게 된다.
문제를 해결하기 위해 useTransition 훅을 사용해보자
const [isPending, startTransition] = useTransition();
useTransition을 호출하면 isPending, startTransition을 반환한다.
isPending은 현재 렌더링 여부를 알려주는 플래그이고 startTransition 함수로 우선순위를 지연 시킬 수 있다.
function App() { const data = ['사과','배','오렌지','바나나','딸기','천례향','귤','자몽','수박','키위','아보카도','참외'] const allData = Array(5000).fill([...data]); const [text,setText] = useState('') const [filterText,setFilterText] = useState('') const [isPending, startTransition] = useTransition() const handleChange = (e) => { setText(e.target.value) startTransition(() => { setFilterText(e.target.value) }) } return ( <div className="App"> <input type="text" onChange={handleChange}/> {text} {isPending ? <p>로딩즁..</p> : <SearchBox data={allData} text={filterText}/>} </div> ); } export default App;
아까 코드에서 text란 상태를 둘다 공유하고 있었기 때문에 상태를 나누었다.
input은 text상태를 사용하고 SearchBox는 filterText를 사용하도록 했다.
이렇게 상태를 나누면 인풋창을 입력시 text 상태를 즉시 업데이트 하고 startTransition으로 filterText의 우선순위를 낮춰 지연 시키게 된다.
그리고 isPending이 true일때 로딩중 ui를 보여주고 false일때 리스트를 보여주도록 했다
이런식으로 하면 리액트는 동시성을 실현하여 text는 즉각적으로 업데이트하고 startTransition은 우선순위를 낮춰가며 text보다 filterText의 상태를 지연시키는 것이다.

useTransition을 사용하기 전보다 인풋창 입력했을때 버벅거리는 증상이 없어졌고 렌더링시 로딩중을 표시 함으로써 훨씬 UX가 향상된 모습을 보여준다.
참고
https://www.jinlog.org/bfa0e261-03d7-46fa-a7e9-2312316bda0c
useTransition
useTransition()을 사용하면 이 동시성 모드의 이점을 살려 작업의 우선순위를 선정해 사용자 경험(UX)를 향상시킬 수 있습니다.
www.jinlog.org
https://blog.bitsrc.io/usetransition-and-usedeferredvalue-in-react-18-5d8a09f8c3a7
useTransition and useDeferredValue in React 18
useTransition and useDeferredValue are two new hooks React introduced with React 18 earlier this year. These two hooks make use of React’s…
blog.bitsrc.io
'react' 카테고리의 다른 글
useState는 비동기적으로 동작한다! (1) | 2024.04.30 |
---|---|
framer-motion으로 리액트에서 애니메이션을 쉽게 ✨ (0) | 2024.04.19 |
react+webpack+tailwindcss 설치하기! (0) | 2022.09.19 |
React hooks를 class components 대신 사용 해야 하는 이유는 뭘까? (0) | 2021.08.27 |
useRef props 전달할때 null 값 문제를 forwardRef를 사용하여 해결하기 (0) | 2021.08.12 |
이챙(leechaeng)
프론트엔드 개발도 하고 뛰기도 하고