일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 비동기
- vanilla-extract
- SWC
- Cache
- MSW
- 쓰레드
- mock service worker
- Critical Rendering Path
- react-query
- styled-component
- JavaScript
- 컴포넌트
- link
- async
- 자바스크립트
- 동기
- sprinkles
- Basic
- React
- 기본
- 아키텍처
- 개발자
- Babel
- 리액트
- front-end mocking
- mockoon
- thread
- 기초
- amplify
- next hydration
- 최적화
- 리액트네이티브
- Concurrent Mode
- 목킹
- react server component
- 캐쉬
- react-native
- CSS-in-JS
- next.js
- 리액트쿼리
- Today
- Total
Don’t worry about failures
useTransition에 대해 본문
이전글에서 리액트의 동시성에 대해 살펴봤었다.
https://sangwonny.tistory.com/78
concurrent mode에 대해
리액트 18버전부터 등장한 개념으로 리액트에서 concurrent(동시성)에 대해 몇년동안 연구하고 분석한 결과 나오게 되었다. Concurrent React 자바스크립트의 특성상 싱글쓰레드로 하나의 작업씩 처리
sangwonny.tistory.com
이번 글에서는 동시성 처리를 위한 훅에 대해 살펴보겠다.
우선 최신 리액트 프로젝트를 생성하면 다음과 같을 것이다.
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
이는 이전버전 17과의 다른점은 ReactDOM.createRoot 부분이다. (이전에는 ReactDOM.render이다)
이를 사용하게 되면 동시성에 대한 기능들을 사용할 수 있다.
startTransition, useTransition
transition은 이전 글에서 살펴 보았듯이, 우선순위가 낮다.
syncLane, InputContinuouseLane, transitionLane, defaultLane 순이다. 이를 리액트의 메소드 혹은 훅으로써 관리를 하고자하는 것이다.
이는 언제 사용할까?
사용자의 상호작용와 렌더링과의 우선순위에서 상호작용을 더 높이고자할 때 사용한다.
예시를 봐보자. 이또한 이전 글의 예시에 연장선이다.
예시 코드를 다시 보면, 입력을 할 때마다 *표시를 길이의 1000배 개수를 렌더링한다.
이렇게 하게되면 input창이 버벅이면서 안좋은 경험을 제공하게 된다.
이를 useTransition을 통해 개선해보자.
function App() {
const [array, setArray] = useState([]);
const inputHandler = useCallback((e) => {
const inputValue = e.target.value;
const newArray = new Array(inputValue.length * 1000);
setArray([...newArray]);
}, []);
return (
<div className="App">
<input onChange={inputHandler}/>
<div style={{display: "flex", flexWrap: "wrap"}}>
{
array.map((value, index, array) => {
return (<div style={{marginTop: 20}} key={index}>
**
</div>);
})
}
</div>
</div>
);
}
useTransition을 통한 개선
const [isPending, startTransition] = useTransition();
const [array, setArray] = useState([]);
const inputHandler = useCallback((e) => {
const inputValue = e.target.value;
startTransition(() => {
const newArray = new Array(inputValue.length * 1000);
setArray([...newArray]);
});
}, []);
return (
<div className="App">
<input onChange={inputHandler}/>
<div style={{display: "flex", flexWrap: "wrap"}}>
{
array.map((value, index, array) => {
return (<div style={{marginTop: 20}} key={index}>
**
</div>);
})
}
</div>
</div>
);
이와 같이 변경해보았다. 실해본결과 input 창에 있었던 버벅임이 다 살아졌다.
이에 대한 플로우를 간단하게 봐보면,
사용자 입력에 대한 우선순위가 더 높기 때문에 입력을 우선적으로 받아지고 그 이후에 setArray에 따른 브라우저 렌더링이 진행이 되는 메커니즘이다.
훅에서는 isPending을 제공하기 때문에 이를 활용하여 로딩 표현 또한 가능한다.
'React' 카테고리의 다른 글
Hydrate에 대해 (0) | 2024.03.22 |
---|---|
React StrictMode에 대해 (0) | 2024.03.21 |
concurrent mode에 대해 (0) | 2024.03.15 |
React Big list state 관리 이슈 (0) | 2022.11.25 |
useCallback과 useMemo에 사용에 대해 (0) | 2022.05.08 |