私たちは、これまでで最も開発者フレンドリーなRelayバージョンであるRelay Hooksをリリースし、本日OSSコミュニティに公開できることを大変嬉しく思います! Relay Hooksは、React Hooksを使用してGraphQLデータをフェッチおよび管理するための一連の新しい、再考されたAPIです。
新しいAPIは、既存のコンテナベースのAPIと完全に互換性があります。新しいコードはRelay Hooksを使用して記述することをお勧めしますが、*既存のコンテナを新しいAPIに移行することはオプションであり、コンテナベースのコードは引き続き機能します*。
これらのAPIは新しくリリースされましたが、テストされていないわけではありません。書き直されたFacebook.comは完全にRelay Hooksで動作しており、これらのAPIは2019年半ばからFacebookでRelayを使用する推奨方法となっています。
さらに、書き直されたガイドツアーと更新されたドキュメントもリリースしています。これらは、Relayを初めて開発して以来、私たちが学んできた、保守性の高いデータ駆動型アプリケーションを構築するためのベストプラクティスをまとめたものです。
Relayを使い始めるのが私たちが望むほど簡単になるまでにはまだ道のりがありますが、これらのステップによってRelayの開発エクスペリエンスが大幅に向上すると信じています。
何がリリースされましたか?
GraphQLデータを操作するための一連のReact HooksベースのAPIであるRelay Hooksをリリースしました。また、より安定したバージョンのfetchQuery
や、getDataID
を使用してRelayでオブジェクト識別子をカスタマイズする機能(サーバーにグローバルに一意のIDがない場合に便利です)など、その他の改善も提供する機会を得ました。
リリースされた内容の完全なリストについては、リリースノートをご覧ください。
Hooks APIの利点は何ですか?
新しくリリースされたAPIは、少なくとも以下の方法で開発エクスペリエンスを向上させます
- クエリをフェッチし、フラグメントでデータをロードし、ページネーション、再フェッチ、ミューテーション、サブスクリプションを行うためのHooksベースのAPIは、一般的に、同等のコンテナベースのソリューションよりもコード行数が少なく、間接性が少なくなります。
- これらのAPIは、より完全なFlowとTypescriptのカバレッジを備えています。
- これらのAPIは、コンパイラ機能を活用して、再フェッチクエリやページネーションクエリの生成など、エラーが発生しやすいタスクを自動化します。
- これらのAPIには、フェッチポリシーを設定する機能が備わっています。これにより、クエリをストアから満たす条件と、ネットワークリクエストを行う条件を決定できます。
- これらのAPIを使用すると、コンポーネントがレンダリングされる前にデータのフェッチを開始できます。これは、コンテナベースのソリューションでは実現できませんでした。これにより、ユーザーにデータがより早く表示されます。
次の例は、新しいAPIの利点のいくつかを示しています。
異なる変数でフラグメントを再フェッチする
まず、Hooks APIを使用して異なる変数でフラグメントを再フェッチする方法を見てみましょう
type Props = {
comment: CommentBody_comment$key,
};
function CommentBody(props: Props) {
const [data, refetch] = useRefetchableFragment<CommentBodyRefetchQuery, _>(
graphql`
fragment CommentBody_comment on Comment
@refetchable(queryName: "CommentBodyRefetchQuery") {
body(lang: $lang) {
text
}
}
`,
props.comment,
);
return <>
<CommentText text={data?.text} />
<Button
onClick={() =>
refetch({ lang: 'SPANISH' }, { fetchPolicy: 'store-or-network' })
}>
>
Translate
</Button>
</>
}
これを同等のコンテナベースの例と比較してください。Hooksベースの例は、行数が少なく、開発者が手動で再フェッチクエリを記述する必要がなく、再フェッチ変数の型チェックが行われ、クエリがストア内のデータから満たされる場合はネットワークリクエストを発行しないことが明示的に示されています。
コンポーネントをレンダリングする前にデータのフェッチを開始する
新しいAPIにより、開発者はコンポーネントのレンダリング前にデータのフェッチを開始することで、ユーザーにコンテンツをより迅速に表示できます。このようにデータをプリフェッチすることは、コンテナベースのAPIでは不可能です。次の例を考えてみましょう
const UserQuery = graphql`
query UserLinkQuery($userId: ID!) {
user(id: $userId) {
user_details_blurb
}
}
`;
function UserLink({ userId, userName }) {
const [queryReference, loadQuery] = useQueryLoader(UserQuery);
const [isPopoverVisible, setIsPopoverVisible] = useState(false);
const maybePrefetchUserData = useCallback(() => {
if (!queryReference) {
// calling loadQuery will cause this component to re-render.
// During that re-render, queryReference will be defined.
loadQuery({ userId });
}
}, [queryReference, loadQuery]);
const showPopover = useCallback(() => {
maybePrefetchUserData();
setIsPopoverVisible(true);
}, [maybePrefetchUserData, setIsPopoverVisible]);
return <>
<Button
onMouseOver={maybePrefetchUserData}
onPress={showPopover}
>
{userName}
</Button>
{isPopoverVisible && queryReference && (
<Popover>
<React.Suspense fallback={<Glimmer />}>
<UserPopoverContent queryRef={queryReference} />
</React.Suspense>
</Popover>
)}
</>
}
function UserPopoverContent({queryRef}) {
// The following call will Suspend if the request for the data is still
// in flight:
const data = usePreloadedQuery(UserQuery, queryRef);
// ...
}
この例では、クエリがローカルキャッシュ内のデータから満たされない場合、ユーザーがボタンにカーソルを合わせたときにネットワークリクエストが開始されます。そのため、ボタンが最終的に押されたとき、ユーザーはコンテンツをより早く見ることができます。
対照的に、コンテナベースのAPIは、コンポーネントがレンダリングされるときにネットワークリクエストを開始します。
データフェッチのためのHooksとSuspense
両方の例でSuspenseが使用されていることに気付いたかもしれません。
Relay Hooksは一部のAPIでSuspenseを使用していますが、*ReactにおけるデータフェッチのためのSuspenseのサポート、一般的なガイダンス、および使用要件はまだ準備できていません*。Reactチームは、今後のリリースに向けてこのガイダンスがどうなるかをまだ定義しています。React 17でSuspenseを使用する場合、いくつかの制限があります。
それでも、これらのAPIがReactの今後のリリースをサポートするための正しい方向に向かっていることを知っているため、Relay Hooksをリリースしました。 RelayのSuspense実装の一部はまだ変更される可能性がありますが、Relay Hooks API自体は安定しています。社内で広く採用されており、1年以上本番環境で使用されています。
このトピックの詳細については、Suspenseの互換性とSuspenseを使用した読み込み状態をご覧ください。
ここからどこへ行くか
謝辞
Relay Hooksのリリースは、React Dataチームだけの仕事ではありませんでした。これを可能にしてくれた貢献者に感謝します
(貢献者リストの日本語訳は省略)
オープンソースプロジェクトrelay-hooks
により、コミュニティはRelayとReact Hooksを試すことができ、貴重なフィードバックを得ることができました。 useSubscription
フックのアイデアは、そのリポジトリのissueから生まれました。このプロジェクトを推進し、オープンソースコミュニティで重要な役割を果たしてくれた@morrysに感謝します。
これを可能にしてくれてありがとう!