ちょうど1週間前、reactチームは新しいRFCについてブログに投稿しました。それがどんな種類の動物で、なぜそれが必要なのかを理解しましょう。
それは何ですか
名前が示すように、Reactサーバーコンポーネントはサーバー上で実行されるコンポーネントです。現在、いくつかの種類のコンポーネントがあります。
クライアントコンポーネント
サーバーコンポーネント
ハイブリッドコンポーネント
クライアントコンポーネント
, , . . .client.js
, ( useState
"" ). . . .server.js
. , .
. . . JSX .
SSR
, SSR
Next.js
. , ? . , SSR
HTML
, . SSR
, . Server Components JSON
virtual dom
.
, , server components.
SSR server components, .
, . , .
, , .server.js
// Note.server.js - Server Component
import db from 'db.server';
// (A1) We import from NoteEditor.client.js - a Client Component.
import NoteEditor from 'NoteEditor.client';
function Note(props) {
const {id, isEditing} = props;
// (B) Can directly access server data sources during render, e.g. databases
const note = db.posts.get(id);
return (
<div>
<h1>{note.title}</h1>
<section>{note.body}</section>
{/* (A2) Dynamically render the editor only if necessary */}
{isEditing
? <NoteEditor note={note} />
: null
}
</div>
);
}
.
, , :
Zero-Bundle-Size Components
, , . , , . , markdown , :
// NoteWithMarkdown.js
// NOTE: *before* Server Components
import marked from 'marked'; // 35.9K (11.2K gzipped)
import sanitizeHtml from 'sanitize-html'; // 206K (63.3K gzipped)
function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text));
return (/* render */);
}
bundle 74 , server components, :
// NoteWithMarkdown.server.js - Server Component === zero bundle size
import marked from 'marked'; // zero bundle size
import sanitizeHtml from 'sanitize-html'; // zero bundle size
function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text));
return (/* render */);
}
, 74 .
Backend
, :
// Note.server.js - Server Component
import fs from 'react-fs';
function Note({id}) {
const note = JSON.parse(fs.readFile(`${id}.json`));
return <NoteWithMarkdown note={note} />;
}
// Note.server.js - Server Component
import db from 'db.server';
function Note({id}) {
const note = db.notes.get(id);
return <NoteWithMarkdown note={note} />;
}
, , 3 :
react-fs
-
react-fetch
-
react-pg
- PostgresSql
, API server component.
Code Splitting
, Code Splitting. , , bundle React.lazy:
// PhotoRenderer.js
// NOTE: *before* Server Components
import React from 'react';
// one of these will start loading *when rendered on the client*:
const OldPhotoRenderer = React.lazy(() => import('./OldPhotoRenderer.js'));
const NewPhotoRenderer = React.lazy(() => import('./NewPhotoRenderer.js'));
function Photo(props) {
// Switch on feature flags, logged in/out, type of content, etc:
if (FeatureFlags.useNewPhotoRenderer) {
return <NewPhotoRenderer {...props} />;
} else {
return <OldPhotoRenderer {...props} />;
}
}
Server Components, :
// PhotoRenderer.server.js - Server Component
import React from 'react';
// one of these will start loading *once rendered and streamed to the client*:
import OldPhotoRenderer from './OldPhotoRenderer.client.js';
import NewPhotoRenderer from './NewPhotoRenderer.client.js';
function Photo(props) {
// Switch on feature flags, logged in/out, type of content, etc:
if (FeatureFlags.useNewPhotoRenderer) {
return <NewPhotoRenderer {...props} />;
} else {
return <OldPhotoRenderer {...props} />;
}
}
, , .
client-server
- , , , .
. , API. graphql/JSON API .
:
// Note.js
// NOTE: *before* Server Components
function Note(props) {
const [note, setNote] = useState(null);
useEffect(() => {
// NOTE: loads *after* rendering, triggering waterfalls in children
fetchNote(props.id).then(noteData => {
setNote(noteData);
});
}, [props.id]);
if (note == null) {
return "Loading";
} else {
return (/* render note here... */);
}
}
Note, . server components , :
// Note.server.js - Server Component
function Note(props) {
// NOTE: loads *during* render, w low-latency data access on the server
const note = db.notes.get(props.id);
if (note == null) {
// handle missing note
}
return (/* render note here... */);
}
したがって、コンポーネントがサーバー上で実行されると、必要なapiと対話し、ユーザーのネットワークを介して1回の反復でデータをコンポーネントに転送できます。その後、コンポーネントの実行結果がユーザーにストリーミングされます。
結果
私の意見では、サーバーコンポーネントには、サスペンス、コンカレントモード、サーバーコンポーネントを組み合わせることで、開発者にとって柔軟性があり、UIを実装するのにユーザーフレンドリーな場所があります。
このRFCとアプローチ、実装、およびAPIは、公式リリースの前に変更される可能性があることを忘れないでください。
サーバーコンポーネントについてどう思いますか?
追加資料
サーバーコンポーネントについて詳しく知りたい場合。