돌아온 탕아, 리액트 (feat. 니꼴라스)

장인배·2022년 1월 15일
0

React

목록 보기
1/1
post-thumbnail

페이스북에서 리액트18에 대한 RC* 버전을 내놓았다. 리액트18이라고 해서 무슨 다른 의미가 있는건 아니고 열여덟번째 버전이라는 뜻이다.

  • Release Candidate: 출시 후보. 베타 서비스는 해당 버전에서 추가된 기능을 확정하는 단계, RC 단계는 이에 대한 안정성을 확보하는 과정으로 볼 수 있다. 소프트웨어 배포 생명 주기 페이지를 참고하면 좋다.

package.json에서 확인해보니

{
   "dependencies": {
      "react": "^18.0.0-rc.0",
      "react-dom": "^18.0.0-rc.0",
  },
}

요런식으로 나온다. 작년 11월에 베타 서비스를 출시한 이후 꽤 빠르게 RC 버전이 나온 것 같다. 정식 버전이 나올 때까지 기능들을 연습해놓았다가 정식 버전이 출시되면 실제 내가 개발하고 있는 서비스에도 적용해볼 생각이다.

기능들을 살펴보니 꽤 흥미로운 지점들이 많았는데, 이번에는 리액트18의 새롭게 추가된 기능들을 간단히 살펴볼 것이다.

리액트18의 주요 기능들은 노마드 코더 니콜라스 형님의 리액트18 요약 영상에서 소개된 내용을 참고했다.


  1. 리액트 서스펜스(React Suspense)

리액트 서스펜스는 <Suspense> 컴포넌트를 사용하여 데이터를 비롯한 무엇이든 "기다릴 수 있도록" 해주는 기능이다. 공식문서에는 기다릴 수 있다는 것에 강조를 하고 있다. 좀 더 나은 사용자 경험을 위한다면 꽤 유용한 기능이 될 수 있다. 페이지 빨리 안 뜬다고 욕 먹을 일을 그나마 줄일 수 있다.

// Before
function Bag(){
  const { data: bag, isLoading } = useQuery("my-bag", callbackFn);
  if(isLoading){
    return <Loader />;
  }
  return <div>{bag.name} is ready.</div>;
}

위의 snippet에서 isLoading과 if절에 해당하는 부분이 데이터를 fetch하는 동안 사용자에게 보여질 로딩화면이다. 이는 보통 Loading state로 통칭한다.

이 로딩화면을 별도 컴포넌트로 분리하여 개발할 수 있도록 해놓은 것이 suspense 기능의 핵심이다.

// After
function Bag(){
  const { data: bag } = useQuery("my-bag", callbackFn);
  return <div>{bag.name} is ready.</div>;
}

function App(){
  return (
    <Suspense fallback={<Loader />}>
    	<Bag />
    </Suspense>
  )
}

App에서 Bag 컴포넌트를 호출할 때 Suspense로 감싼다음 fallback 프로퍼티에 Loading state를 구현해주면 된다.

이와 같이 Suspense를 이용하여 Loading state를 구현하면 코드의 가독성이 높아진다. Loading state 컴포넌트는 Loading 기능에, Bag 컴포넌트는 Bag을 표현하는 기능에 더 집중할 수 있다. 하나의 함수(여기서는 컴포넌트)는 하나의 기능을 수행하도록 한다는 클린코드 원칙에도 더욱 부합한다고 할 수 있다.


  1. SSR(Server Side Rendering)

기존 리액트는 CSR(Client side rendering) 방식을 채택하고 있다. 클라이언트가 서버에 페이지 자원을 요청하면 리액트 코드가 포함되어 있는 모든 자바스크립트 파일들은 브라우저로 전달된다. 전달된 코드들은 브라우저 위에서 렌더링을 거치고 이후 사용자에게 보인다.

사정이 이렇다보니 클라이언트는 실컷 기다린 다음에야 페이지 코빼기라도 볼 수 있다. 이에 대한 해결책으로 제시된 것이 SSR이다.

클라이언트가 서버에 페이지 요청을 하면, 서버에 있는 리액트 코드는 페이지를 재빨리 생성하여 껍데기만 UI만 먼저 보내준다. 그 이후 자바스크립트 파일들을 추가로 클라이언트에게 보낸다.

이를 Hydration이라고 하는데 한국말로는 '수화'라고 한다. 하지만 나는 수화라는 표현보다는 '적심'이라는 표현이 더 이해하기 쉽지 않을까 한다. hydro는 물을 뜻하고 -ate는 동사화, -ion은 명사를 만드는 접미사니 물로 적시는 걸 뜻하는 바와 다르지 않다.

빈 껍데기만 있는 HTML UI는 마치 마른 땅과 같고, 자바스크립트가 가미된 전체 페이지는 물로 충분히 적셔져 비옥한 땅과 같다. 당연히 클라이언트 입장에서는 메마른 땅보다는 촉촉히 적셔진 땅이 더욱 다니기 편할 수밖에 없다. (CSR과 SSR을 자세하게 비교하는 글은 추후 작성 예정이다.)

SSR을 사용하고 있는 리액트 기반 웹 프레임워크에는 Next.js가 있으며, 우리 회사에서는 이를 채용하여 실제 서비스에서 활용하고 있다.

CSR과 SSR에 대한 설명이 약간 길어졌는데, 리액트18로 다시 돌아와보자. 리액트18에서는 Suspense에 SSR을 적용할 수 있다. 데이터를 fetch하는 동안 Loading state를 보여주고, 데이터를 가져온 이후에는 결과 컴포넌트를 반환한다.

클라이언트는 이 덕분에 데이터를 fetch하고 있는 다른 컴포넌트를 기다릴 필요없이 먼저 렌더링되는 컴포넌트들을 볼 수 있다. 심지어 클라이언트가 특정 컴포넌트에 이벤트를 발생시켰을 때 그 컴포넌트부터 hydrate하기 때문에 유저에게 더욱 빠르게 페이지를 보여줄 수 있다.

profile
보험하는 개발자입니다.

0개의 댓글