useId
리액트 18에서 추가 된 중복되지 않은 고유한 값을 생성할 때 사용하는 훅입니다.
문법
const uuid = useId();
사용법
import { useId } from "react";
const App = () => {
const uuid = useId();
return (
<div>
<form action="">
<label htmlFor={uuid}></label>
<input type="text" id={uuid} />
</form>
</div>
);
};
export default App;
useTransition
리액트 18에서 추가된 훅으로 동시성 모드(Concurrent Mode)에서 제공하는 훅입니다. 동시성 모드란, 리액트가 작업들을 무조건 순차적으로 처리하는 것이 아니라 각 작업에 우선 순위를 지정하여 동시 다발적으로 처리하는 개념을 말합니다.
문법
const [pending, startTransition] = useTransition(); // pending이 true면 로딩중, false면 완료
예제
아래 코드는 입력 요소의 값이 변경될 때마다 인위적으로 무거운 상태 변경 작업을 처리하고 있는 코드입니다. 일반적으로 리액트는 작업을 순차적으로 처리하기 때문에 이 코드를 실행해보면 입력 요소의 값 변경에 렉이 걸립니다.
import { useState } from "react";
const UseTransition = () => {
const [input, setInput] = useState("");
const [dummy, setDummy] = useState<number[]>([]);
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInput(e.target.value);
const i: number[] = [];
for (let j = 0; j < 20000; j++) {
i.push(j);
}
setDummy((d) => [...d, ...i]);
};
return (
<>
<h1>UseTranstion</h1>
<input type="text" value={input} onChange={onChange} />
<ul>
{dummy.map((d) => (
<li key={d}>{d}</li>
))}
</ul>
</>
);
};
export default UseTransition;
이때, 아래처럼 동시성 모드를 지원하는 useTransition을 사용하여 무거운 변경 작업의 우선 순위를 낮추게 되면 입력 값의 렉을 해결할 수 있습니다.
import { useState, useTransition } from "react";
const UseTransition = () => {
const [input, setInput] = useState("");
const [dummy, setDummy] = useState<number[]>([]);
const [pending, startTransition] = useTransition();
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInput(e.target.value);
startTransition(() => {
const i: number[] = [];
for (let j = 0; j < 20000; j++) {
i.push(j);
}
setDummy((d) => [...d, ...i]);
});
};
return (
<>
<h1>UseTranstion</h1>
<input type="text" value={input} onChange={onChange} />
{!pending ? (
<ul>
{dummy.map((d, i) => (
<li key={i}>{d}</li>
))}
</ul>
) : (
<p>loading</p>
)}
</>
);
};
export default UseTransition;
useDeferredValue
리액트 18에서 추가된 훅으로 동시성 모드(Concurrent Mode)에서 제공하는 훅입니다. 동시성 모드란, 리액트가 작업들을 무조건 순차적으로 처리하는 것이 아니라 각 작업에 우선 순위를 지정하여 동시 다발적으로 처리하는 개념을 말합니다.
문법
const deferredDummy = useDeferredValue(value);
예제
아래 코드는 입력 요소의 값이 변경될 때마다 인위적으로 무거운 상태 변경 작업을 처리하고 있는 코드입니다. 일반적으로 리액트는 작업을 순차적으로 처리하기 때문에 이 코드를 실행해보면 입력 요소의 값 변경에 렉이 걸립니다.
import { useState } from "react";
const UseTransition = () => {
const [input, setInput] = useState("");
const [dummy, setDummy] = useState<number[]>([]);
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInput(e.target.value);
const i: number[] = [];
for (let j = 0; j < 20000; j++) {
i.push(j);
}
setDummy((d) => [...d, ...i]);
};
return (
<>
<h1>UseTranstion</h1>
<input type="text" value={input} onChange={onChange} />
<ul>
{dummy.map((d) => (
<li key={d}>{d}</li>
))}
</ul>
</>
);
};
export default UseTransition;
이때, 아래처럼 동시성 모드를 지원하는 useTransition을 사용하여 무거운 변경 작업의 우선 순위를 낮추게 되면 입력 값의 렉을 해결할 수 있습니다.
import { useDeferredValue, useState } from "react";
const UseDeferredValue = () => {
const [input, setInput] = useState("");
const [dummy, setDummy] = useState<number[]>([]);
const deferredDummy = useDeferredValue(dummy);
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInput(e.target.value);
const i: number[] = [];
for (let j = 0; j < 20000; j++) {
i.push(j);
}
setDummy((d) => [...d, ...i]);
};
return (
<>
<h1>UseDeferredValue</h1>
<input type="text" value={input} onChange={onChange} />
<ul>
{deferredDummy.map((d, i) => (
<li key={i}>{d}</li>
))}
</ul>
</>
);
};
export default UseDeferredValue;
useTransition vs useDeferredValue
동시성 모드를 지원하는 훅인 useTransition과 useDeferredValue는 둘 다 모두 작업의 우선 순위를 낮게 낮추어서 처리한다는 특징이 있습니다. 하지만, useTransition은 함수를, useDeferredValue는 값을 처리한다는 점이 다르며, 처리해야 하는 작업이 단순히 값인지 로직인지에 따라 구분해서 사용하면 됩니다.
💡 단, 동시성 모드를 지원하는 훅을 사용하게 되면 불필요한 렌더링이 추가로 발생할 수 있으니
사용하기 전에 신중히 생각해봐야 합니다.
[스나이퍼 팩토리 2기 과정]
본 학습 자료 및 코드는 수코딩님의 자료를 이용하였습니다. [수코딩(https://www.sucoding.kr)] 출처
'프론트엔드(Web) > React' 카테고리의 다른 글
리액트 컨텍스트 - useContext, zustand (0) | 2024.08.28 |
---|---|
리액트 메모이제이션- useCallback,useMemo,React.memo,useReducer (4) | 2024.08.27 |
리액트 훅 기본 - (useState(),useRef(),useEffect(),useLayoutEffect() (1) | 2024.08.27 |
리액트 - 컴포넌트 기본문법(컴포넌트 생성, props, children, 조건부 및 반복 , 이미지 렌더링) (0) | 2024.08.25 |
리액트 - 폰트 지정하는 방법 (0) | 2024.08.21 |