FacebookのソフトウェアエンジニアであるRobert Balicki氏とJuan Tejada氏は最近、GraphQLデータをフェッチし、管理するための新しいAPIの集合であるRelay Hooksをリリースした。Relay HooksはFacebook.comの書き換えでバトルテストが行われており、FacebookでRelayを使用するための推奨されている方法である。
Relay Hooksは、React HooksベースのAPIのセットであり、GraphQLデータを使った作業をシンプルにし、開発者のエクスペリエンスを向上させることを目的としている。Relay Hooksには、クエリのフェッチ、フラグメントを含むデータの読み込み、ページネーション、再フェッチ、ミューテーション、サブスクリプションのためのAPIが含まれている。Balicki氏とTejada氏によると、Relay Hooksには、同等のコンテナベースのソリューションよりもコード行が少なく、間接参照が少ないという大きな利点がある。他にも、より完全なFlowとTypescriptのカバー、エラーが発生しやすいタスクの自動化(再フェッチおよびページネーションクエリ)、ポリシー設定のフェッチ、コンポーネントがレンダリングされる前にデータをフェッチすることによる体感の待ち時間短縮といった利点がある。
投機的フェッチは、必要になる前にデータをフェッチすることでユーザエクスペリエンスを向上させようとするものである。たとえば、リソースヒントを使用すると、開発者は宣言的にリソースをプリフェッチできる。Balicki氏とTejada氏は、ユーザがボタンにカーソルを合わせたときにRelay Hooksを利用してデータをフェッチするプリフェッチの例を別に示している。ホバーしてからボタンをクリックするまでの遅延が150ミリ秒未満になることはめったになく(読者はここでクリック速度をテストできる)、ユーザは100ミリ秒未満の遅延に気づかない。そのため、ホバーでフェッチすると、データが到着して表示されるまでについて、理想的なユーザエクスペリエンスのために、250ミリ秒の猶予がある可能性がある。コード例は次のとおりである。
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);
// ...
}
前述のコードでは、maybePrefetchUserData
がホバーで実行され、ローカルキャッシュからクエリを実行できない場合にネットワーク要求をトリガーする。Balicki氏とTejada氏は次のように説明した。
ボタンが最後に押されると、ユーザはコンテンツをより早く見ることができます。対照的に、[既存の]コンテナベースのAPIは、コンポーネントがレンダリングされるときにネットワークリクエストを開始します。
Redditのある開発者は、ページネーションの開発者エクスペリエンスが向上したと報告した。
私はこれを使ってみることにとてもワクワクしています。ページネーションの単純化は非常に大きい[私の意見では]
Relay HooksはさらにReact Strict Modeと完全に互換性があり、2019年半ばからFacebookでRelayを使用するために推奨されている方法である。ただし、新しいAPIは、既存のコンテナベースAPIと完全に互換性がある。