Sai*_*Akh 5 apollo reactjs graphql react-apollo
在前端,我使用 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
}
}
}
Run Code Online (Sandbox Code Playgroud)
初始加载$filterByBook变量设置为null,因此查询正确返回所有节点的所有页面(查询返回分页结果)。然后,通过点击过滤器(按书籍过滤),另一个 graphql 查询正在发出,但它总是返回相同的data. 这是过滤组件的代码片段
renderFilters() {
const { listOfBooksWithChapters, refetch } = this.props;
return (
<Row>
<FilterBooks
onBookTitleClickParam={(onBookTitleClickParam) => {
return refetch({
variables: {
limit: 3,
after: 0,
filterByBook: onBookTitleClickParam
}
})
}}
listOfBooksWithChapters={listOfBooksWithChapters}
/>
</Row>
)
}
Run Code Online (Sandbox Code Playgroud)
而且,这里是列表视图组件没有导入的完整代码
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 width="100%" src={ytDefaultThumbnail} alt="video image" />
<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);
Run Code Online (Sandbox Code Playgroud)
题:
为什么refetch函数返回数据而不考虑新变量filterByBook?如何检查variables我提供给refetch函数的对象?我是否需要将我从refetch函数接收到的数据重新映射回组件props?
编辑:
我找到了找到variable我提供给查询的对象的方法,并发现variable过滤事件中的对象返回此数据
variables:Object
after:0
limit:3
variables:Object
after:0
filterByBook:"2"
limit:3
Run Code Online (Sandbox Code Playgroud)
您可以通过在 useQuery 中添加refetch来做到这一点
const {loading, data, error,refetch} = useQuery(GET_ALL_PROJECTS,
{
variables: {id: JSON.parse(localStorage.getItem("user")).id}
});
Run Code Online (Sandbox Code Playgroud)
然后调用函数refetch()
const saveChange = input => {
refetch();
};
Run Code Online (Sandbox Code Playgroud)
或者
const saveChange = input => {
setIsOpen(false);
addProject({
variables: {
createBacklogInput: {
backlogTitle: backlogInput,
project:id
}
}
}).then(refetch);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13057 次 |
| 最近记录: |