이제 본격적으로 fetch로 값을 가져와서 병렬적으로 비트코인의 정보와 시세를 가져와 보도록 하겠습니다. 일단 코드를 보고 설명 하도록 하겠습니다.
/pages/coins.server.tsx
import { Suspense } from "react";
const cache: any = {};
function fetchData(url: string) {
if (!cache[url]) {
throw Promise.all([
fetch(url)
.then((r) => r.json())
.then((json) => (cache[url] = json)),
new Promise((resolve) =>
setTimeout(resolve, Math.round(Math.random() * 1555))
),
]);
}
return cache[url];
}
function Coin({ id, name, symbol }: any) {
console.log(
"check cache",
cache[`https://api.coinpaprika.com/v1/tickers/${id}`]
);
const {
quotes: {
USD: { price },
},
} = fetchData(`https://api.coinpaprika.com/v1/tickers/${id}`);
return (
<span>
{name} / {symbol}: ${price}
</span>
);
}
function List() {
const coins = fetchData(
"https://api.coinpaprika.com/v1/coins"
);
return (
<div>
<h4>List is done</h4>
<ul>
{coins.slice(0, 10).map((coin: any) => (
<li key={coin.id}>
<Suspense fallback="Loading...">
<Coin {...coin} />
</Suspense>
</li>
))}
</ul>
</div>
);
}
export default function Coins() {
console.log("asdf");
return (
<div>
<h1>Welcome to RSC</h1>
<Suspense fallback="Rendering in the server...">
<List />
</Suspense>
</div>
);
}
export const config = {
runtime: "edge",
};
저는 이 코드를 짜고 감탄을 금치 못했습니다. 여태까지 뭔가 많은 Data-Fetching방법을 봐왔고, 이와 관련된 기술들을 보왔는데, React18의 SCR은 정말 대단합니다.
이를 실행한 결과를 일단 보겠습니다.
저는 위와같이 처음에는 GET https://api.coinpaprika.com/v1/coins
을 불러오기 전까지 "Rendering in the server..."을 Suspense의 fallback으로 주었습니다. 그리고 이의 자식으로 List를 주었습니다. List는 이제 coin의 정보를 하나하나 활용하여 코인의 tickers(시세)를 불러왔습니다.
그리고 이 Coin컴포넌트도 안에서 fetchData로 데이터가 잘 불러와졌는지 Promise로 반환하며 관리하고 있습니다. 따라서 Coin의 시세 정보가 불러와지면 이의 name / symbol / price를 렌더링하게 했습니다. 그리고 이 데이터가 불러와 지기 전에는 Suspense로 Loading...을 렌더링하게 했습니다.
Coin컴포넌트로 List컴포넌트 모두 다 데이터가 있다는 가정하에 코딩할 수 있었습니다. 이는 React가 지향하는 선언적 코딩방식에 부합하게 짠것이라고 생각됩니다. 추가적으로 각각의 아이템을 렌더링하는데에 인위적으로 지연시간을 실제 데이터를 불러오는것을 Promise.all으로 합쳐서 Suspense이 확인하게 냅뒀습니다.
서버에 의해 모든 컴포넌트가 평행적으로 렌더링됩니다. 이 모든 컴포넌트들이 다른 컴포넌트가 렌더링되는걸 기다리지 않아도 된다는게 너무 좋은 기능같다고 생각됩니다. 이 컴포넌트들이 서버에서 렌더링되고 있고 http스트리밍을 사용해 리액트가 결과를 받으면 Suspense부분에 보여주는걸 바꿔주고 있는것입니다. 각기 다른 속도로 서버에서 렌더링되는게 정말 미쳤다고 생각이 듭니다.
그리고 소스코드를 보면 위와같은 데이터를 볼 수 있을겁니다.
지금은 우리가 api를 직접 호출하고 있지만, 미래에는 컴포넌트에서 프리즈마를 사용해 바로 호출이 가능할 겁니다. 그래도 유저는 로딩 상태를 확인할 수 있습니다. 이렇게 클라이언트에서 컴포넌트를 렌더링하는 중이라도, 서버사이드에서 컴포넌트를 렌더링할 수 있음을 알아봤습니다.
'Web > NextJs' 카테고리의 다른 글
[ Next.js - DeepDive ] - REACT18 - Sever Components 2 (0) | 2022.08.13 |
---|---|
[ Next.js - DeepDive ] - REACT18 - Suspense 2 (0) | 2022.08.13 |
[ Next.js - DeepDive ] - REACT18 - Sever Components (0) | 2022.08.13 |
[ Next.js - DeepDive ] - REACT18 - Suspense (0) | 2022.08.12 |
[ Next.js - DeepDive ] - Data Fetching Reca (0) | 2022.08.12 |