React 18 에서 달라지는점

katanazero·2022년 3월 18일
4

react

목록 보기
14/15

2022년 3월 8일에 React v18 RC(Release Candidate)가 공개되었습니다.

이제 조금만 있으면, 우리는 정식으로 출시된 React v18을 사용할 수 있습니다.
React v17은 2020년 10월에 출시가 되었는데, 추가된 기능은 없었습니다.


Concurrent Rendering

자바스크립트는 단일쓰레드기반 언어입니다. 한번에 한가지일만 처리가 가능합니다.
그래서 자바스크립트에서는 task 를 나눠서 우선순위에 따라 task 를 번갈아가면서 실행을 한다.
병렬처리와는 개념이 다르다. 실제로 동시에 처리하는게 아닌 task 를 빠르게 번갈아가면서 처리하기때문에 마치 동시에 수행이 되는거처럼 보이는거다.

Concurrent Rendering은 Suspense 및 startTransition(), useDeferredValue() API와 같이 새롭게 제공되는 많은 기능을 지원하는 배후 기능이다. -> 이를 통해서 얻고자하는거는 UI업데이트를 사용자 친화적으로 만들고자함이다.

Suspense

이전에는 데이터를 조회하는데, 조회 상태를 가지고 조건부 렌더링을 해줬습니다.
UI요소는 항상 조회상태에 의존을 하고있었습니다.
Suspense를 사용하여, 이러한 UI요소가 조회 상태에 대한 의존을 해결하도록 도와줍니다.

const [loading, setLoading] = useState(true);

if myData != null {
    setLoading(true); 
} 

<>
    { !loading && 
        <MyComponent />
    }
    { loading && 
        <Loading />
    }
<>
<Suspense fallback={<Loading/>}>
    <MyComponent myData={myData}/>
</Suspense> 

Automatic Batching

이전에는 단일 이벤트 핸들러내에서만 일괄처리가 발생하였습니다. 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!)
  }

이제 위와 같은 코드들도 일괄처리를 해주기때문에, 불필요한 렌더링이 발생하지 않습니다.

New APIs

  • useTransition()
    useTransition은 다음 화면으로 transition하기 전에 컨텐츠가 로드 될 때까지 대기함으로써 컴포넌트가 바람직하지 않은 로딩 상태를 피할 수 있게 해줍니다. 또한 컴포넌트가 더 중요한 업데이트를 즉시 렌더링 할 수 있도록 후속 렌더링까지 느린 데이터 가져오기를 지연시킬 수 있습니다.
    useTransition 훅은 2개의 배열을 반환합니다.
    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()
    특정 update를 지연시킬수 있습니다. 디바운스처럼 사용이 가능합니다.
    지연시킴으로써, 렌더링 순서제어가 가능합니다.
const deferredValue = useDeferredValue(value, { timeoutMs: 4000 }); 

return (
  <div>
    <MyComponent value={deferredValue} />
  </div>
);

ReactDOM.render -> ReactDOM.createRoot

// 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의 멋진 새 기능을 사용할 수 없습니다.


profile
developer life started : 2016.06.07 ~ 흔한 Front-end 개발자

0개의 댓글