react-apollo 中的 data.refetch() 函数如何工作
Posted
技术标签:
【中文标题】react-apollo 中的 data.refetch() 函数如何工作【英文标题】:How data.refetch() function from react-apollo works 【发布时间】:2017-12-04 00:29:02 【问题描述】:在前端,我正在使用 ReactJS 并尝试在列表视图中内置过滤选项。列表视图通过发出此 graphql 查询正确地从 graphql 端点获取数据:
query getVideos($filterByBook: ID, $limit: Int!, $after: ID)
videosQuery(filterByBook: $filterByBook, limit: $limit, after: $after)
totalCount
edges
cursor
node
id
title
ytDefaultThumbnail
pageInfo
endCursor
hasNextPage
在初始加载时$filterByBook
变量设置为null
,因此查询正确返回所有节点的所有页面(查询返回分页结果)。然后,通过单击过滤器(按书过滤)另一个 graphql 查询正在发出,但它总是返回相同的data
。这是过滤组件的代码sn-p
renderFilters()
const listOfBooksWithChapters, refetch = this.props;
return (
<Row>
<FilterBooks
onBookTitleClickParam=(onBookTitleClickParam) =>
return refetch(
variables:
limit: 3,
after: 0,
filterByBook: onBookTitleClickParam
)
listOfBooksWithChapters=listOfBooksWithChapters
/>
</Row>
)
而且,这里是列表视图组件没有导入的完整代码
class VideoList extends React.Component
constructor(props)
super(props);
this.subscription = null;
componentWillUnmount()
if (this.subscription)
// unsubscribe
this.subscription();
renderVideos()
const videosQuery = this.props;
return videosQuery.edges.map(( node: id, title, ytDefaultThumbnail ) =>
return (
<Col sm="4" key=id>
<Card>
<CardImg top src=ytDefaultThumbnail />
<CardBlock>
<CardTitle>
<Link
className="post-link"
to=`/video/$id`>
title
</Link>
</CardTitle>
</CardBlock>
</Card>
</Col>
);
);
renderLoadMore()
const videosQuery, loadMoreRows = this.props;
if (videosQuery.pageInfo.hasNextPage)
return (
<Button id="load-more" color="primary" onClick=loadMoreRows>
Load more ...
</Button>
);
renderFilters()
const listOfBooksWithChapters, refetch = this.props;
return (
<Row>
<FilterBooks
onBookTitleClickParam=(onBookTitleClickParam) =>
return refetch(
variables:
limit: 3,
after: 0,
filterByBook: onBookTitleClickParam
)
listOfBooksWithChapters=listOfBooksWithChapters
/>
</Row>
)
render()
const loading, videosQuery = this.props;
if (loading && !videosQuery)
return (
<div> /* loading... */</div>
);
else
return (
<div>
<Helmet
title="Videos list"
meta=[
name: 'description',
content: 'List of all videos'
] />
<h2>Videos</h2>
this.renderFilters()
<Row>
this.renderVideos()
</Row>
<div>
<small>(videosQuery.edges.length / videosQuery.totalCount)</small>
</div>
this.renderLoadMore()
</div>
);
export default compose(
graphql(VIDEOS_QUERY,
options: () =>
return
variables:
limit: 3,
after: 0,
filterByBook: null
,
;
,
props: ( data ) =>
const loading, videosQuery, fetchMore, subscribeToMore, refetch = data;
const loadMoreRows = () =>
return fetchMore(
variables:
after: videosQuery.pageInfo.endCursor,
,
updateQuery: (previousResult, fetchMoreResult ) =>
const totalCount = fetchMoreResult.videosQuery.totalCount;
const newEdges = fetchMoreResult.videosQuery.edges;
const pageInfo = fetchMoreResult.videosQuery.pageInfo;
return
videosQuery:
totalCount,
edges: [...previousResult.videosQuery.edges, ...newEdges],
pageInfo,
__typename: "VideosQuery"
;
);
;
return loading, videosQuery, subscribeToMore, loadMoreRows, refetch ;
),
graphql(LIST_BOOKS_QUERY,
props: ( data ) =>
const listOfBooksWithChapters = data;
return listOfBooksWithChapters ;
),
)(VideoList);
问题:
为什么refetch
函数返回数据而不考虑新变量filterByBook
?如何检查我提供给refetch
函数的variables
对象?我是否需要将从refetch
函数接收到的数据重新映射回组件props
?
编辑:
我找到了找到我提供给查询的 variable
对象的方法,并发现过滤事件上的 variable
对象返回此数据
variables:Object
after:0
limit:3
variables:Object
after:0
filterByBook:"2"
limit:3
【问题讨论】:
【参考方案1】:你可以通过在 useQuery 中添加 refetch 来做到这一点
const loading, data, error,refetch = useQuery(GET_ALL_PROJECTS,
variables: id: JSON.parse(localStorage.getItem("user")).id
);
然后调用函数refetch()
const saveChange = input =>
refetch();
;
或
const saveChange = input =>
setIsOpen(false);
addProject(
variables:
createBacklogInput:
backlogTitle: backlogInput,
project:id
).then(refetch);
【讨论】:
【参考方案2】:似乎refetch
函数并不意味着重新获取具有不同变量集的数据(请参阅此discussion)。
在this article的帮助下,我终于成功地解决了我的问题
【讨论】:
以上是关于react-apollo 中的 data.refetch() 函数如何工作的主要内容,如果未能解决你的问题,请参考以下文章
React-Apollo - 查询 - renderProp:反应警告:无法对未安装的组件执行反应状态更新
使用 react-apollo 自定义 InputTypes