reactjs - React-apollo 中的 data.refetch() 函数如何工作

标签 reactjs graphql apollo react-apollo

在前端,我使用 ReactJS 并尝试在 ListView 中内置过滤选项。 ListView 通过发出此 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>
    )
  }

并且,这是未导入 ListView 组件的完整代码

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);

问题:

为什么refetch函数返回数据而不考虑新变量filterByBook?如何检查我向 refetch 函数提供了哪些 variables 对象?我是否需要将从 refetch 函数接收到的数据重新映射回组件 props

编辑:

我找到了查找我提供给查询的variable对象的方法,并发现过滤事件上的variable对象返回此数据

variables:Object
    after:0
    limit:3
        variables:Object
        after:0
        filterByBook:"2"
        limit:3

最佳答案

您可以通过在 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);

关于reactjs - React-apollo 中的 data.refetch() 函数如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44839791/

相关文章:

javascript - react 测试 : Cannot read property 'toLowerCase' of undefined

reactjs - 这两种rootSaga配置有什么区别

mongodb - 看不到关系 - Loopback 4 + MongoDB + openapi-to-graphql

reactjs - 无法使用上下文提供程序对已卸载的组件执行 React 状态更新

reactjs - 等待 DOM 上的 useCallback 效果

javascript - 如何修复 `data-rbd-draggable-context-id` 不匹配。服务器 : "1" Client: "0"' with react-beautiful-dnd and next. js

graphql - Prisma graphql 计算字段

reactjs - 如何在电容器应用程序处于后台时继续运行 apollo 订阅?

reactjs - Graphql:Typescript + Jest + Relay + Jest 似乎无法集成在一起

graphql - Apollo:从远程模式扩展类型