我可以在没有 apollo / react-query 的情况下将 React 无限滚动与 GraphQL 和 datoCMS 一起使用吗?

问题描述

我想对新闻进行分页,或使用无限滚动,但由于网站已建成然后作为静态文件提供,我不确定最好的方法是什么?

是否可以不使用 apollo 或 react-query?

我确实尝试了 react-query,但无法让它看到我的 datoCMS 端点。

(更新:下面关于承诺的评论

import React from 'react'
import { useQuery } from 'react-query'
import gql from 'graphql-tag'
import { GraphQLClient,request } from 'graphql-request'

export const useGQLQuery = (key,query,variables,config = {}) => {
  const endpoint = `https://graphql.datocms.com/`

  const client = new GraphQLClient(endpoint,{
    headers: {
      authorization: `Bearer MY_TOKEN_HERE`
    }
  });
  // use await to wait until promise has been fulfilled
  const fethData = async () => await request(endpoint,client,variables)
  return useQuery(key,fethData,config); // useQuery from react-query
};

const GET_ALL_NEWS_CONTENT = gql`
    query {
      allNews {
        slug
        id
        title
      }
    }
`;

const AllNews = () => {
  // Fetch data from custom hook that uses React-Query
  const { data,isLoading,error } = useGQLQuery('allNews',GET_ALL_NEWS_CONTENT)
  console.log(data)

  if (isLoading) return <div>Loading…</div>
  if (error) return <div>Something went wrong…</div>

  return (
    <>
      <div className="generic-page">

        <h2>All News</h2>

        <div>
          {data.allNews.map(news => (
            <div key={news.title}>{news.title}</div>
          ))}
        </div>
      </div>
    </>
  )
};

export default AllNews;

解决方法

在 datoCMS 和 react-query 社区的帮助下,这里是解决方案! ……

import React,{ useState } from 'react'
import { useQuery } from 'react-query'
import gql from 'graphql-tag'
import { GraphQLClient } from 'graphql-request'

export const useGQLQuery = (key,query,variables) => {
  const endpoint = `https://graphql.datocms.com/`

  const client = new GraphQLClient(endpoint,{
    headers: {
      authorization: `Bearer MY_TOKEN_HERE`,}
  });

  return useQuery(
    key,() => client.request(query,variables),{ keepPreviousData: true }
  );  // useQuery from react-query
};

const GET_ALL_NEWS_CONTENT = gql`
    query GetAllNewsContent ($first: IntType = 10,$skip: IntType = 0) {
      allNews(first: $first,skip: $skip,orderBy: _createdAt_DESC) {
        id
        title
        slug
      }
    }
`;


export default function AllNews({ newscount }) {
  const first = 5
  let [skip,skipNews] = useState(0)
  // Fetch data from custom hook that uses React-Query
  const { data,status } = useGQLQuery(
    ['allNews',skip],GET_ALL_NEWS_CONTENT,{ skip,first }
  );
  const itemCount = Math.ceil(newscount / first);

  return (
    <div className="generic-page">

      <button className="example_b"
        onClick={() => skipNews(old => Math.max(old - 5,0))}
        disabled={skip === 0}
      >
        <span>Previous Page</span>
      </button>{' '}

      <button className="example_f"
        onClick={() => skipNews(old => Math.max(old + 5,0))}
        // Disable the Next Page button when the next skip would be higher than the meta count
        disabled={skip + 5 > newscount}
      >
        <span>Next Page</span>
      </button>

      <h2>All News</h2>

      <p>Page {skip / 5 + 1} of {itemCount}</p>

      {status === 'loading' && (
        <div>Loading…</div>
      )}

      {status === 'error' && (
        <div>Something went wrong…</div>
      )}

      {status === 'success' && (
        <div>
          {data.allNews.map(news => (
            <div key={news.title}>{news.title}</div>
          ))}
        </div>
      )}

    </div>
  )
};