無限のスクロールと
14371 ワード
このHackathonに参加することによって、私は技術的にAPIを構築する方法を学びました.私はアポロ法などを発見しています
だから、私は念願のアプリの心の中に持っていた機能の一つは無限スクロールです.私は多くのダムデータを持っていませんが、私はまだこれが新しいthingi - i ' sを学ぶのが大好きです.
これを実行する方法の調査の中で、アポロのfetchMore それは完全に私の要求に合っています.
すぐにこのプロジェクトを開始するにはジャンプするには、“安い”私はできるように、私はデータベースとしてMongoDBのアトラスを使用することを決めたので、私はDBについて多くの心配し、残りに集中する必要はありません.つのアプリケーションの要件の1つは、ユーザーの位置によって(最初にFarthestに近い)、その後、最近の日付で投稿をソートすることです.
私は自由層クラスタを使用することを選んだので、
それでは、始めましょう.まず、GQLクエリを
私が欲しいものは、ユーザーがスクロールして、ページの底に達するとき、私はより多くのポストを得たいです.ここでオフセットが入るところです.私は
に
また帰ります
私は多くを学びました.私が反応してコード化した時から、それもしばらくありました.フェアゲーム.間違いなく、サーバー上のDBをソートし、クライアント上でUIを処理するより効率的な方法があります(アポロのInmemoryCacheの代わりに反応状態を使用することを選んだ).おそらく多くの時間とリソースを使うと、これらのことは改善されます.
それまで、ハッピーハッキング!🚀
fetchMore
私はそれが超クールだと思う!だから、私は念願のアプリの心の中に持っていた機能の一つは無限スクロールです.私は多くのダムデータを持っていませんが、私はまだこれが新しいthingi - i ' sを学ぶのが大好きです.
これを実行する方法の調査の中で、アポロのfetchMore それは完全に私の要求に合っています.
すぐにこのプロジェクトを開始するにはジャンプするには、“安い”私はできるように、私はデータベースとしてMongoDBのアトラスを使用することを決めたので、私はDBについて多くの心配し、残りに集中する必要はありません.つのアプリケーションの要件の1つは、ユーザーの位置によって(最初にFarthestに近い)、その後、最近の日付で投稿をソートすることです.
私は自由層クラスタを使用することを選んだので、
aggregate
or mapReduce
それは私が理想的に使うものです.しかし、まあ、私はJavaScriptのメソッドを使用する必要があります迅速かつ簡単ですが、演奏者としてではなく😅.それでは、始めましょう.まず、GQLクエリを
GET_POSTS
そして、アポロのuseQuery
ページがマウントされたときにポストを取得します. const GET_POSTS = gql`
query GetPosts($offset: Int) {
posts(offset: $offset) {
content {
...
}
hasMore
}
}
`;
const { loading, error, fetchMore } = useQuery(GET_POSTS, {
onCompleted: data => {
const { content, hasMore } = data.posts;
setPosts(content);
setHasMorePosts(hasMore);
},
});
注意fetchMore
usequeryで破壊されたプロパティでは?これはアポロによって基本的にGraphSQLクエリを再利用するために与えられた関数/メソッドですが、変数を渡すのは自由です.私が欲しいものは、ユーザーがスクロールして、ページの底に達するとき、私はより多くのポストを得たいです.ここでオフセットが入るところです.私は
onScroll
私が添付したイベントdiv
そのようなポストを含む<div onScroll={onScroll}>...</div>
そして、実装のためのコードです const onScroll = e => {
// if div is at the bottom, fetch more posts
if (e.target.scrollTop + e.target.clientHeight === e.target.scrollHeight) {
// if there are no more posts to fetch, don't do anything
if (!hasMorePosts) return;
setTimeout(() => {
setIsFetchMoreLoading(true);
fetchMorePosts();
}, 300);
return;
}
};
const fetchMorePosts = async () => {
setOffset(prev => prev + 1);
const fetchedMore = await fetchMore({
variables: { offset: offset + 1 },
});
const { content, hasMore } = fetchedMore.data.posts;
setPosts(previousPosts => [...previousPosts, ...content]);
setHasMorePosts(hasMore);
setIsFetchMoreLoading(false);
};
それはかなり簡単です.The onScroll
イベントはスクロールイベントを聞きます、そして、ユーザーがページの底にあるならば、私はより多くのポストを得たいです.しかし、取得するより多くのポストがないならば、私はちょうど戻りたいです、そして、何もしません.に
fetchMorePosts
関数は、アポロの呼び出しfetchMore
新しいオフセット変数を指定します.今、リゾルバで何が起こっているかを示します.const resolvers = {
Query: {
posts: async (_parent, { offset }, { db, loggedUser }, _info) => {
if (!loggedUser) throw new AuthenticationError('you must be logged in');
const { location } = await db.collection('users').findOne({ username: loggedUser.username });
let posts;
const allPosts = await db
.collection('posts')
.find()
.toArray();
const sortedByDate = allPosts.reverse();
// mongodb mapReduce not supported for free tier cluster :(
// Workaround -> handle sort using JS methods
if (location) {
const compareDistance = (postLat, postLng) => calcDistance(postLat, postLng, location.lat, location.lng);
// sort by distance (closest -> farthest)
posts = sortedByDate.sort(
(a, b) => compareDistance(a.location.lat, a.location.lng) - compareDistance(b.location.lat, b.location.lng)
);
} else {
posts = sortedByDate;
}
// sort by offset
if (offset) {
// if offset is not null (not the initial fetch)
const newOffsetValue = offset * FETCH_LIMIT;
const payload = posts.slice(newOffsetValue, FETCH_LIMIT + newOffsetValue);
return { content: payload, hasMore: !!payload.length };
} else {
const payload = posts.slice(0, FETCH_LIMIT);
return { content: payload, hasMore: !!payload.length };
}
}
}
}
オフセットは、どこから始めたいのか、制限するかということです.したがって、オフセットが未定義である最初のフェッチでif(offset)
他のブロックは、0からの投稿を制限したいと思います.から次のクエリfetchMore
のオフセットを与える1
, で、配列をスライスします(5,10)
. また帰ります
hasMore
フロントエンド側のフェッチをより多くの状態にしたい場合の応答で.私は多くを学びました.私が反応してコード化した時から、それもしばらくありました.フェアゲーム.間違いなく、サーバー上のDBをソートし、クライアント上でUIを処理するより効率的な方法があります(アポロのInmemoryCacheの代わりに反応状態を使用することを選んだ).おそらく多くの時間とリソースを使うと、これらのことは改善されます.
それまで、ハッピーハッキング!🚀
Reference
この問題について(無限のスクロールと), 我々は、より多くの情報をここで見つけました https://dev.to/chewypao/infinite-scrolling-with-graphql-and-apollo-528kテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol