Reactjs 阿波罗客户&x27;s updateQuery';使用新数据重新渲染组件
我有一个组件,查询GraphQL后端以返回作者的姓名和简历,以及相关作者发布的所有帖子。我正试着在这里对返回的帖子进行分页。我的质询如下: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:
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);