Reactjs 阿波罗客户&x27;s updateQuery';使用新数据重新渲染组件

Reactjs 阿波罗客户&x27;s updateQuery';使用新数据重新渲染组件,reactjs,graphql,apollo-client,Reactjs,Graphql,Apollo Client,我有一个组件,查询GraphQL后端以返回作者的姓名和简历,以及相关作者发布的所有帖子。我正试着在这里对返回的帖子进行分页。我的质询如下: query users($username: String!, $postLimit: Int!, $postStart: Int!) { users(limit: 1, where: { username: $username }) { _id firstName lastName bio posts(sort:

我有一个组件,查询GraphQL后端以返回作者的姓名和简历,以及相关作者发布的所有帖子。我正试着在这里对返回的帖子进行分页。我的质询如下:

query users($username: String!, $postLimit: Int!, $postStart: Int!) {
  users(limit: 1, where: { username: $username }) {
    _id
    firstName
    lastName
    bio
    posts(sort: "createdAt:DESC", limit: $postLimit, start: $postStart, where: {isPublished: true}) {
      title
    }
  }
  postsConnection(where: {isPublished: true}){
    groupBy{
      author{
        key
        connection{
          aggregate{
            count
          }
        }
      }
    }
  }
}
因此,运行此查询的组件正在使用:

///components/blog/SingleAuthor.jsx
从“@material ui/core/styles/withStyles”导入withStyles;
从“道具类型”导入道具类型;
从“React”导入React;
从“./Loading”导入加载;
从“@apollo/react hooks”导入{useQuery};
从“阿波罗客户端”导入{NetworkStatus};
从“graphql标签”导入gql;
从“../../apollo/schemas/getUserQuery.graphql”导入getUserQuery;
从“@material ui/core/Grid”导入网格;
从“下一个/头”导入头
从“@material ui/core/Typography”导入排版;
从“@material ui/core/Button”导入按钮;
从“@material ui/core/CircularProgress”导入CircularProgress;
常量样式=(主题)=>({
根:{},
});
export const GET_USER=gql`${getUserQuery}`;
导出常量getUserQueryVars={
启动后:0,
职位限制:2,
};
const SingleAuthor=(道具)=>{
常数{
班级,
作者:,
}=道具;
常数{
加载,
错误,
数据,
费特莫尔,
网络状态,
}=使用查询(
获取用户,
{
//变量:{username:authorSlug},
变量:{username:authorSlug,…getUserQueryVars},
//将此值设置为true将使组件在
//“网络状态”会发生变化,因此我们可以知道它是否正在抓取
//更多数据
notifyOnNetworkStatusChange:true,
},
);
const loadingMorePosts=networkStatus==networkStatus.fetchMore;
const loadMorePosts=()=>{
费特莫尔({
变量:{
postStart:posts.length
},
updateQuery:(上一个结果,{fetchMoreResult})=>{
如果(!fetchMoreResult){
返回以前的结果
}
//console.log('previousResult',previousResult);
//log('fetchMoreResult',fetchMoreResult);
设oldRes={…previousResult};
让newRes={…fetchmoresult};
让oldPosts=oldRes.users[0].posts;
让newPosts=newRes.users[0].posts;
oldRes.users[0].posts=[…oldPosts,…newPosts];
//console.log(“最终结果”,oldRes);
返回Object.assign({},previousResult{
//将新发布结果附加到旧发布结果
用户:[…oldRes.users],
})
}
})
};
如果(错误)返回,则存在错误!;
if(加载和加载更多帖子)返回;
const{users,postsConnection}=数据;
const[user]=用户;
常数{
_身份证,
名字,
姓,
生物
帖子,
}=用户;
const postCount=postsConnection.groupBy.author.find({key}=>key===\u id).connection.aggregate.count;
const areMorePosts=posts.length
{bio}

{posts.map((post)=>{ 返回( {post.title} ); })} {areMorePosts&&( {加载更多帖子( ) : ( 显示更多 )} )} ); }; SingleAuthor.propTypes={ 类:PropTypes.shape({ root:PropTypes.string, }).要求, }; 导出默认样式(样式)(SingleAuthor);
如您所见,我目前正试图使用
load more
按钮一次只返回2篇文章。单击此按钮时,将触发一个
loadMorePosts()
方法,用于检索接下来的两篇文章,依此类推。处理方法时,按钮将替换为加载进度图标(
CircularProgress

然而,这是行不通的。该方法确实可以检索新帖子,但它不会触发UI的重新呈现,从而导致进度图标永久保留,检索到的帖子永远不会显示在浏览器中。如何解决这个问题

作为参考,回购协议的价格上涨至,其结果可在现场查看


p.S.:查询可以在GraphQL端点进行测试:。

我想你不小心又发布了查询,而不是组件代码。我的错,只是添加了正确的代码。谢谢你指出。你解决这个问题了吗?
// /components/blog/SingleAuthor.jsx
import withStyles from '@material-ui/core/styles/withStyles';
import PropTypes from 'prop-types';
import React from 'react';

import Loading from './Loading';
import { useQuery } from '@apollo/react-hooks';
import { NetworkStatus } from 'apollo-client';
import gql from 'graphql-tag';
import getUserQuery from '../../apollo/schemas/getUserQuery.graphql';
import Grid from '@material-ui/core/Grid';
import Head from 'next/head'
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import CircularProgress from '@material-ui/core/CircularProgress';

const styles = (theme) => ({
  root: {},
});

export const GET_USER = gql`${getUserQuery}`;

export const getUserQueryVars = {
  postStart: 0,
  postLimit: 2,
};

const SingleAuthor = (props) => {
  const {
    classes,
    authorSlug,
  } = props;

  const {
    loading,
    error,
    data,
    fetchMore,
    networkStatus,
  } = useQuery(
    GET_USER,
    {
      // variables: {username: authorSlug},
      variables: {username: authorSlug, ...getUserQueryVars},
      // Setting this value to true will make the component rerender when
      // the "networkStatus" changes, so we'd know if it is fetching
      // more data
      notifyOnNetworkStatusChange: true,
    },
  );

  const loadingMorePosts = networkStatus === NetworkStatus.fetchMore;

  const loadMorePosts = () => {
    fetchMore({
      variables: {
        postStart: posts.length
      },
      updateQuery: (previousResult, { fetchMoreResult }) => {
        if (!fetchMoreResult) {
          return previousResult
        }
        // console.log('previousResult', previousResult);
        // console.log('fetchMoreResult', fetchMoreResult);
        let oldRes = {...previousResult};
        let newRes = {...fetchMoreResult};
        let oldPosts = oldRes.users[0].posts;
        let newPosts = newRes.users[0].posts;
        oldRes.users[0].posts = [...oldPosts, ...newPosts];
        // console.log('Final result', oldRes);

        return Object.assign({}, previousResult, {
          // Append the new posts results to the old one
          users: [...oldRes.users],
        })
      }
    })
  };

  if (error) return <div>There was an error!</div>;
  if (loading && !loadingMorePosts) return <Loading />;

  const { users, postsConnection } = data;
  const [user] = users;
  const {
    _id,
    firstName,
    lastName,
    bio,
    posts,
  } = user;

  const postCount = postsConnection.groupBy.author.find(({key}) => key === _id).connection.aggregate.count;
  const areMorePosts = posts.length < postCount;

  console.log('postCount', postCount);
  console.log('areMorePosts', areMorePosts);

  return (
    <>
      <Head>
        <title>{`${firstName} ${lastName}`}</title>
        <meta name="description" content={`Posts by ${firstName} ${lastName}`} key="postDescription" />
      </Head>
      <Grid item className={classes.root}>
        <h1>{firstName} {lastName}</h1>
        <p>{_id}</p>
        <p>{bio}</p>
        {posts.map((post) => {
          return (
            <h2>{post.title}</h2>
          );
        })}
        {areMorePosts && (
          <div className={classes.root}>
            {loadingMorePosts ? (
              <CircularProgress style={{opacity: 0.3}} />
            ) : (
              <Button color="primary" className={classes.root} onClick={loadMorePosts}>Show more</Button>
            )}
          </div>
        )}
      </Grid>
    </>
  );
};

SingleAuthor.propTypes = {
  classes: PropTypes.shape({
    root: PropTypes.string,
  }).isRequired,
};

export default withStyles(styles)(SingleAuthor);