Apollo Client - fetchMore 组件更新问题
Posted
技术标签:
【中文标题】Apollo Client - fetchMore 组件更新问题【英文标题】:Apollo Client - fetchMore component update problem 【发布时间】:2020-03-27 06:42:32 【问题描述】:在我的 NextJS 应用程序与 MongoDB API 后端接口 - 通过 GraphQL 管理,我正在尝试实现 Apollo fetchMore
功能,以更新负责从数据集合中加载更多项目的组件。
在页面呈现时,组件本身会显示一个包含 10 个元素的“图库”作为其原生功能,并通过 GraphQL 起始查询填充。然后,我添加了一个“加载更多”按钮来触发fetchMore
功能。 UX 预计,如果用户单击正确的按钮,除了之前的 10 个元素之外,还将加载更多的 10 个元素 - 基本上是一个经典的异步无限加载示例。
通过检查应用程序,我注意到两个查询都已成功返回 - 初始化一个和“加载更多 10 个项目”也由 fetchMore
管理 - 但后者在执行后触发组件的更新它正在使用启动器查询而不是fetchMore
重新初始化。
澄清一下:在“加载更多”上单击,而是查看加载的下一个 10 个画廊元素 - 因此最终显示总共 20 个 - 组件刷新并显示起始 10 个元素,就像它的初始初始化一样 - 完全忽略fetchMore
操作,即使该操作正在被调用、执行并收到返回的填充 200 响应。
因为这是我第一次使用它,我不知道我的实现中是否遗漏了一些东西,或者我需要修复一些东西。不管怎样,就这样吧:
由于各种原因,我在父组件中运行查询,然后将数据作为道具传递给子组件:
家长
// Initialization, etc.
[...]
const loading: loadingIndex, error: errorIndex, data: dataIndex, fetchMore: fetchMoreIndex = useQuery(ARTICLE_QUERY.articles.indexArticles,
// Last 30 days
variables:
live: live,
limit: 10
);
// Exception check
if (errorIndex)
return <ErrorDb error=errorIndex />
// DB fetching check
if (loadingIndex)
return (
<section className="index-articles">
<h6>Index - Articles</h6>
<aside className="articles__loading">
<h6>Loading</h6>
</aside>
</section>
);
const articles = dataIndex.queryArticleContents;
return (
<IndexArticles labels=props.labels articles=articles fetchMore=fetchMoreIndex />
);
儿童
// Initialization, etc.
[...]
let limit = 10; // My query hypothetically limiter
const IndexArticles = (props) =>
useEffect(() =>
// This is a getter method responsible to manage the ```fetchMore``` response
getArticles(props.articles, props.fetchMore);
);
return (
<>
// Component sections
[...]
// Load button
props.fetchMore &&
<button className="articles__load" title=props.labels.index.title tabIndex=40>props.labels.index.cta</button>
</>
);
function getArticles(articles, fetchMore)
// Yes, I'm using jQuery with React. Just ignore it
$('.articles__load').on('click tap', function(e)
e.preventDefault();
$(this).addClass('hidden');
$('.articles__loading').removeClass('hidden');
fetchMore(
variables:
// Cursor is being pointed to the last available element of the current collection
lastLoaded: articles.length,
limit: limit += 10
,
updateQuery: (prev, fetchMoreResult, ...rest) =>
$('.articles__loading').addClass('hidden');
$(this).removeClass('hidden');
if (!fetchMoreResult)
return prev;
return
...fetchMoreResult,
queryArticleContents: [
...prev.queryArticleContents,
...fetchMoreResult.queryArticleContents
]
);
);
有没有人经历过或者曾经经历过这个案例?
提前感谢您的帮助
【问题讨论】:
【参考方案1】:正如官方社区所建议的,我的配置缺少关于查询选项中的notifyOnNetworkStatusChange: true
,它负责更新组件并附加新数据。
通过这种方式更改代码:
家长
const
loading: loadingIndex,
error: errorIndex,
data: dataIndex,
// Add networkStatus property too in order to use notifyOnNetworkStatusChange properly
networkStatus: networkStatusIndex
fetchMore: fetchMoreIndex = useQuery(ARTICLE_QUERY.articles.indexArticles,
// Last 30 days
variables:
live: live,
limit: 10
,
// Important for component refreshing with new data
notifyOnNetworkStatusChange: true
);
问题已经解决了。
【讨论】:
以上是关于Apollo Client - fetchMore 组件更新问题的主要内容,如果未能解决你的问题,请参考以下文章
Apollo 客户端 fetchMore 来自 useQuery 触发两个网络请求
如何将 apollo 客户端 fetchMore updateQuery 转换为 apollo 缓存合并功能?
React/Apollo fetchMore 重新加载整个页面
Apollo fetchMore 更新的 props 不重新渲染组件