TIR ##2 [What You Need to Know About React 18]
학습을 목적으로 Medium에서 읽은 글을 번역한 글입니다.
번역이 완벽하지 않을 수 있고,
직역하기보다는 문맥에 맞추어 자연스럽게 정리하려고 했습니다.
오류나, 개선하면 좋을 부분들에 대한 피드백은 언제나 환영합니다.😁
What You Need to Know About React 18
페이스북 팀이 리액트 버전 18에 대한 계획을 발표했다.
이 버전에서는 많은 흥미로운 기능들을 리액트 자체적으로 제공한다.
out of the box : 기본적으로 제공되는 기능, 특히 소프트웨어의 기능은 구성이나 수정없이 특별한 설치 직후 또는 심지어 특별한 설치 없이도 작동하는 제품의 기능입니다.
이러한 기능들은 사용자의 경험을 향상시킬 뿐만 아니라 개발자의 삶을 편하게 만들어 준다.
이번 글에서는 리액트 18에서 업데이트 될 주요기능 세가지를 소개하려고 한다.
📌 1. Automatic Batching
Batching(일괄 업데이트)이란 리액트에서 좀 더 나은 성능을 위해 한번의 re-rendering을 통해 여러개의 state값의 업데이트를 그룹화 하는 것이다.
예로, 한번의 클릭 이벤트로 2개의 state값이 변경될 경우 리액트는 항상 한번의 re-render를 실행하게 된다.
아래의 코드를 실행시키게 되면, 클릭을 할때마다 2개의 state값을 변경함에도 불구하고, 리액트는 한번의 렌더링을 진행한다는 점을 알 수 있다.
import React, { useState } from "react";
const App = () => {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
const handleClick = () => {
setCount((c) => c + 1); //Does not re-render yet
setFlag((f) => !f); //Does not re-render yet
// React will only re-render once at the end (that`s batching!)
};
console.log("rendering");
return (
<div>
<button onClick={handleClick}>Next</button>
<h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
</div>
);
};
export default App;
이러한 특징은 불필요한 렌더링을 막기 때문에 성능면에서 좋다.
또한 모든 state값이 아니라 하나의 일부만 업데이트 되어 업데이트가 미처 완료되지 않은 상태에서 렌더링을 보여주는 현상을 방지하여 버그의 원인을 막을 수 있다.
이러한 방식은 식당 웨이터가 첫 주문만 받고 주방으로 달려가는 것이 아니라 주문이 끝날때까지 기다리는 것을 연상시킨다.
하지만 리액트는 일괄업데이트(batch update)를 처리할 때 일관적이지 않다.
예로, 만일 위의 예제에 나와있는 handleClick 함수내에 데이터를 받아오는 부분이 포함되었다면(fetch data) 리액트는 모든 업데이트를 일괄적으로 처리하지 않고, 2개의 독립적인 업데이트로 처리하게 될것이다.
이런식으로 일괄 업데이트가 일관적이지 못한 이유는 리액트의 일괄 업데이트는 브라우저 이벤트(click 등..)에만 적용되는데, 아래의 예는 이벤트 처리(click)가 끝난 후에 state값이 변경되는 상황이기 때문이다.
import React, { useState } from "react";
const App = () => {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
const handleClick = () => {
fetchSomething().then(() => {
// React 17 and earlier does NOT batch these:
setCount((c) => c + 1); // Cause of re-render
setFlag((f) => !f); // Cause of re-render
});
};
return (
<div>
<button onClick={handleClick}>Next</button>
<h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
</div>
);
};
export default App;
(이후 리액트 18에서 업데이트 될) 자동 일괄 업데이트(automatic batching)에서는 state값이 설정되는 위치에 상관없이 한번만 re-render를 진행하게 될 것이다.
만약 batch update를 원하지 않는다면?
이 경우에는 react-dom에서 제공하는 flushSync 메서드를 사용할 수 있다.
import { flushSync } from 'react-dom'; // Note: react-dom, not react
function handleClick() {
flushSync(() => {
setCounter(c => c + 1);
});
// React has updated the DOM by now
flushSync(() => {
setFlag(f => !f);
});
// React has updated the DOM by now
}
https://github.com/reactwg/react-18/discussions/21
📌 2. SSR support for Suspense
이 기능은 기본적으로 SSR(Server Side Rendering) 로직의 확장 기능이다.
일반적인 리액트 SSR 애플리케이션은 이러한 과정을 따른다.
- 서버는 화면에 보여지는 UI와 관련된 데이터를 가져온다.
- 서버는 애플리케이션 전체를 HTML로 렌더링 한 후에 클라이어트측에 대한 응답으로 보낸다.
- 클라이언트는 HTML을 제외한 자바스크립트 번들을 다운받는다.
- 마지막으로 클라이언트는 자바스크립트 로직들을 HTML과 연결한다. (hydration)
위와 같은 일반적인 SSR 애플리케이션의 문제점은 이후의 단계로 넘어가기 전에 위의 단계들이 한번에 처리되어야 한다는 점이다.
이러한 문제점은 애플리케이션의 초기 로딩시, 조금 느리고 사용자 입력에 대한 반응이 없도록 만들 수 있다.
리액트 18에서는 이러한 문제를 해결하려고 하였다.
<Suspense> 컴포넌트는 애플리케이션을 위에서 말한 단계들을 거치는 작은 단위로 나누어 주게 된다.
따라서 사용자가 한번에 interactve한 페이지를 볼 수 있게 해준다.
이부분에 대한 자세한 설명은 https://github.com/reactwg/react-18/discussions/37 링크내의
React 18: Streaming HTML and Selective Hydration 파트에 자세히 나와있다.
📌 3. Transition
이것은 앞으로 공개될 굉장한 기능이다.
이 기능은 큰화면에서 자주 업데이트가 일어나는 문제를 사용자가 해결할 수 있도록 해준다.
예를 들어, input의 값에 따라 데이터를 필터링하는 경우, 우리는 사용자가 입력한 값과 해당 값에 따라 필터링되는 데이터를 다루기 위해 input의 value를 컴포넌트내의 state로 선언하여 가지고 있어야 한다.
사용자가 글자를 입력할 때마다 컴포넌트는 input 값을 업데이트 할 것이고 해당 값을 통해 화면에 보여지는 데이터 목록을 바꿔줄 것이다.
큰 화면에서 이러한 업데이트가 일어날 경우, 모든 것이 렌더링 되는 동안 페이지 지연이 발생하여 사용자가 입력이나 다른 interaction에 대해 느리거나 반응이 없다고 느껴질 수 있다.
데이터 목록이 길지 않더라도 각 아이템 자체가 복잡하게 설계되어 있거나 어떠한 키를 입력하는지에 따라 다를 수 있다. 또한 이러한 렌더링 방식을 최적화 할 수 있는 제대로 된 방법이 없을 수도 있다.
개념적으로 이러한 상황에서의 문제는 발생해야 하는 두가지 다른 업데이트가 존재한다는 것이다.
첫번째 업데이트는 급한 업데이트로 주변의 UI요소들을 (잠재적으로라도) 변경할 수 있는 input 값이다.
두번째 업데이트는 덜 급한 업데이트로 검색 키워드(input 값)에 따른 결과값을 보여준다.
// Urgent: Show what was typed
setInputValue(input);
// Not urgent: Show the results
setSearchQuery(input);
새로운 startTransition API는 업데이트에 'transitions' 를 표시할 수 있는 기능을 제공함으로써 이러한 문제를 해결한다.
import { startTransition } from 'react';
// Urgent: Show what was typed
setInputValue(input);
// Mark any state updates inside as transitions
startTransition(() => {
// Transition: Show the results
setSearchQuery(input);
});
📌 React 18 Working Group
facebook은 유명한 라이브러리의 저자, 유지관리자들로 구성된 working group을 만들어 해당 기능들에 대한 피드백을 받기 위해 토의를 진행하고 있다.
리액트 18의 업데이트가 좋은 점은 무언가 없어지는 변화가 아니라는 것이다.
그러므로 현재 작업중인 작업물의 리액트 버전을 업데이트 하더라도 아예 코드변경이 없거나 아주 적은 양의 코드 변경으로 새로운 기능을 이용할 수 있다.
원문
https://javascript.plainenglish.io/what-you-need-to-know-about-react-18-54070f6bc4a1
What You Need to Know About React 18
The Facebook team has released an upcoming plan for React 18 features
javascript.plainenglish.io