2022년 3월 8일에 React v18 RC(Release Candidate)가 공개되었습니다.
이제 조금만 있으면, 우리는 정식으로 출시된 React v18을 사용할 수 있습니다.
React v17은 2020년 10월에 출시가 되었는데, 추가된 기능은 없었습니다.
자바스크립트는 단일쓰레드기반 언어입니다. 한번에 한가지일만 처리가 가능합니다.
그래서 자바스크립트에서는 task 를 나눠서 우선순위에 따라 task 를 번갈아가면서 실행을 한다.
병렬처리와는 개념이 다르다. 실제로 동시에 처리하는게 아닌 task 를 빠르게 번갈아가면서 처리하기때문에 마치 동시에 수행이 되는거처럼 보이는거다.
Concurrent Rendering은 Suspense 및 startTransition(), useDeferredValue() API와 같이 새롭게 제공되는 많은 기능을 지원하는 배후 기능이다. -> 이를 통해서 얻고자하는거는 UI업데이트를 사용자 친화적으로 만들고자함이다.
이전에는 데이터를 조회하는데, 조회 상태를 가지고 조건부 렌더링을 해줬습니다.
UI요소는 항상 조회상태에 의존을 하고있었습니다.
Suspense를 사용하여, 이러한 UI요소가 조회 상태에 대한 의존을 해결하도록 도와줍니다.
const [loading, setLoading] = useState(true);
if myData != null {
setLoading(true);
}
<>
{ !loading &&
<MyComponent />
}
{ loading &&
<Loading />
}
<>
<Suspense fallback={<Loading/>}>
<MyComponent myData={myData}/>
</Suspense>
이전에는 단일 이벤트 핸들러내에서만 일괄처리가 발생하였습니다. React v18에서는 무관하게 자동으로 일괄처리를 해줍니다.
// 이전에는 아래코드로 인해, 리렌더링이 각각 발생하였습니다.
fetch('http://example.com/data.json').then(() => {
setIsLoading(false);
setData(data);
setError(null);
});
function handleClick() {
fetchSomething().then(() => {
// React 17과 이전 버전에서는 이 업데이트들이 handleClick이 *진행되는 중*이 아닌, *완료된 후의* 콜백에서 실행되기 때문에 일괄처리 되지 않았다.
setCount((c) => c + 1); // 리렌더링 발생
setFlag((f) => !f); // 리렌더링을 발생
});
}
function handleClick2() {
setCount(c => c + 1); // 아직 렌더링 안했어요!
setFlag(f => !f); // 아직 렌더링 안해요!!
// React는 이 끝에서 리렌더링을 한번만 합니다. (that's batching!)
}
이제 위와 같은 코드들도 일괄처리를 해주기때문에, 불필요한 렌더링이 발생하지 않습니다.
useTransition()
startTransition
: callback을 받는 함수isPending
: boolean 값, transition 완료를 알려줌
const SUSPENSE_CONFIG = { timeoutMs: 2000 };
function App() {
const [resource, setResource] = useState(initialResource);
const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);
return (
<>
<button
disabled={isPending}
onClick={() => {
startTransition(() => {
const nextUserId = getNextId(resource.userId);
setResource(fetchProfileData(nextUserId));
});
}}
>
Next
</button>
{isPending ? " Loading..." : null}
<Suspense fallback={<Spinner />}>
<ProfilePage resource={resource} />
</Suspense>
</>
);
}
useDeferredValue()
const deferredValue = useDeferredValue(value, { timeoutMs: 4000 });
return (
<div>
<MyComponent value={deferredValue} />
</div>
);
// The old way:
ReactDOM.render(
<App />,
document.getElementById('root')
);
// The new way:
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
ReactDOM.render() 코드를 계속 사용이 가능하지만 콘솔에 오류가 발생하고 이 React v18의 멋진 새 기능을 사용할 수 없습니다.