만약에 타이핑을 할때마다 그 타이핑한 값들을 10000개씩 불러오는 컴포넌트가 있다고 가정해보자.
/* eslint-disable */
import './App.css';
import { useState,} from 'react';
let a = new Array(10000).fill(0);
function App() {
let[name, setName] = useState(0);
return (
<div className="App">
<input onChange={(e) => {
setName(e.target.value)
}}></input>
{
a.map(() => {
return <div>{name}</div>
})
}
</div>
);
}
export default App;
직접 작성해보면 인풋창에서 타이핑을 할때마다 10000개의 값이 창에 띄어지는것이기 때문에
반응속도가 현저히 늦어지는것을 확인해 볼 수 있다.
이럴때 useTransition을 사용하면 저 속도저하를 일으키는 state 변경함수를 다른 코드들보다 나중에 실행시켜준다.
state 변경함수의 실행시점을 뒤로 미뤄줄 수 있다.
import './App.css';
import { useState, useTransition } from 'react'; // useTransition import 하기
let a = new Array(10000).fill(0);
function App() {
let[name, setName] = useState(0);
let [isPending, startTransition] = useTransition() // 불러오기
return (
<div className="App">
<input onChange={(e) => {
startTransition(() => { // 성능 저하 일으키는 state 변경함수 감싸주기
setName(e.target.value)
})
}}></input>
{
a.map(() => {
return <div>{name}</div>
})
}
</div>
);
}
export default App;
위처럼 startTransition 을 이용하면 반응속도가 나아진 것을 볼 수 있다.
그리고 저 isPending 은 startTransition 함수가 실행중일때 true 가 되는데,
{
isPending ? '로딩중' :
a.map(() => {
return <div>{name}</div>
})
}
이런식으로 코드를 짜면 타이핑을 할때 로딩중이 나타나다가 저 startTransition 함수가 실행이 다 되면 없어진다.
위의 startTransition 과 마찬가지로 useDeferredValue 를 사용하면 똑같이 코드 실행 순서를 뒤로 미룰 수 있다.
/* eslint-disable */
import './App.css';
import { useDeferredValue, useState, useTransition } from 'react';
let a = new Array(10000).fill(0);
function App() {
let[name, setName] = useState(0);
let [isPending, startTransition] = useTransition()
let state = useDeferredValue(name);
return (
<div className="App">
<input onChange={(e) => {
setName(e.target.value)
}}></input>
{
a.map(() => {
return <div>{state}</div>
})
}
</div>
);
}
export default App;
이런식으로 useDeferred( ) 안에 state를 넣는다. 이렇게 되면 ( ) 안에 들어간 state 가
변경 될때 실행시점을 뒤로 미뤄주고, 그걸 변수에 담는다.