Reactjs react apollo中data.refetch()函数的工作原理

Reactjs react apollo中data.refetch()函数的工作原理,reactjs,graphql,apollo,react-apollo,Reactjs,Graphql,Apollo,React Apollo,在前端,我正在使用ReactJS并尝试在列表视图中构建一个过滤选项。列表视图通过发出以下graphql查询从graphql端点正确获取数据: query getVideos($filterByBook: ID, $limit: Int!, $after: ID) { videosQuery(filterByBook: $filterByBook, limit: $limit, after: $after) { totalCount edges {

在前端,我正在使用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查询,但它总是返回相同的
数据。下面是用于筛选组件的代码片段

  renderFilters() {
    const { listOfBooksWithChapters, refetch } = this.props;

    return (
      <Row>
        <FilterBooks
          onBookTitleClickParam={(onBookTitleClickParam) => {
            return refetch({
              variables: {
                limit: 3,
                after: 0,
                filterByBook: onBookTitleClickParam
              }
            })
          }}
          listOfBooksWithChapters={listOfBooksWithChapters}
        />
      </Row>
    )
  }

看来,
refetch
函数并不意味着使用不同的变量集来重新蚀刻数据(见此)

在他的帮助下,我终于成功地解决了我的问题

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);
variables:Object
    after:0
    limit:3
        variables:Object
        after:0
        filterByBook:"2"
        limit:3