How data.refetch() function from react-apollo works
Solution 1
you can do it by adding refetch in useQuery
const {loading, data, error,refetch} = useQuery(GET_ALL_PROJECTS,
{
variables: {id: JSON.parse(localStorage.getItem("user")).id}
});
then call function refetch()
const saveChange = input => {
refetch();
};
OR
const saveChange = input => {
setIsOpen(false);
addProject({
variables: {
createBacklogInput: {
backlogTitle: backlogInput,
project:id
}
}
}).then(refetch);
Solution 2
It seem that refetch
function is not meant to refetch data with different variables set (see this discussion).
I finally and successfully solved my issue with the help from this article
SaidAkh
Updated on June 29, 2022Comments
-
SaidAkh almost 2 years
On the frontend, I am using ReactJS and trying to build-in a filtering option to a list view. The list view correctly getting data from graphql endpoint by issuing this graphql query:
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 } } }
On the initial load
$filterByBook
variable is set tonull
, so the query correctly returns all pages for all nodes (query returns a paginated result). Then, by clicking on the filter (filter by book) another graphql query is issuing, but it always returns the samedata
. Here is a code snippet for filtering componentrenderFilters() { const { listOfBooksWithChapters, refetch } = this.props; return ( <Row> <FilterBooks onBookTitleClickParam={(onBookTitleClickParam) => { return refetch({ variables: { limit: 3, after: 0, filterByBook: onBookTitleClickParam } }) }} listOfBooksWithChapters={listOfBooksWithChapters} /> </Row> ) }
And, here is complete code without imports for the list view component
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);
Question:
Why
refetch
function returns data without taking into account new variablefilterByBook
? How to check whichvariables
object I supplied to therefetch
function? Do I need to remap data that I receive fromrefetch
function back to the componentprops
?EDIT:
I found the way to find what
variable
object I supplied to the query and found thatvariable
object on filtering event returns this datavariables:Object after:0 limit:3 variables:Object after:0 filterByBook:"2" limit:3