首页 > 解决方案 > react-apollo Query:从a获取数据的正确方法零件

问题描述

我正在尝试将 Query 组件中的数据转换为我可以呈现的内容。我有这个执行查询的函数,我的组件的渲染方法调用这个函数。我的问题是,我如何将数据转化为我可以使用的东西?

查询功能:

protected queryFoos() {
  const { match: { params } } = this.props;
  const projectId  = params.projectId;
  const { query, dataKey } = fooGql.list;

  return (
    <Query query={query} variables={{ [RouteId.Project]: projectId }}>

      {({ data, error, loading }: QueryResult) => {
        if (loading) { return <div>Loading...</div>; }
        if (error) { return <div>{error}</div>; }

        const listFoos = plainToClassFromExist(new Foo(), data);
        const variablesList = data.listFoos.items;
        // this.setState({ foos: foosList}); // <= this doesn't work

        return listFoos;
       }}

    </Query>
  )
}

还有我调用查询函数的组件:


...

state = {
  foos: [],
}

protected renderContent(project: Project) {
  // query all foos related to the project

  return (
    {project &&
          <Grid container alignItems="stretch">
            <Grid item xs={12}<Typography>Foos</Typography></Grid>
              <Grid item xs={12}>
                {this.queryFoos()}
                <EntityTable entities={this.state.foos}/>
              </Grid>
          </Grid>
       </Grid>
    }
  );
}

标签: reactjstypescriptgraphqlreact-apollo

解决方案


<Query>组件旨在以渲染道具模式的形式提供数据,所以它应该像

  <Grid item xs={12}>
    <Query query={query} variables={{ [RouteId.Project]: projectId }}>
      {({ data, error, loading }: QueryResult) => {
        // ... processing data into listFoos ...
        return
          loading ? <div>Loading</div>
          : error ? <div>{error}</div>
          : <EntityTable entities={listFoos} />;
      }}
    </Query>
  </Grid>

...从利用渲染道具模式的组件设置状态是一项额外的工作,如果我真的需要它,我会考虑使用不同的模式,例如withQuery整个组件的 HOC(使用它你可以获得结果为组件的道具,即在整个组件中可用),提供查询需求道具(例如变量)有点不同,但文档非常清楚如何做到这一点(通常这些需要是整个组件的道具);或新的useQuery钩子。

如果您只需要抽象出一些查询设置/结果处理,您可以在查询上创建一个组件:

const QueryFoos = (props: RequiredProps) => {
  // setup
  return (
    <Query query={query} variables={{ [RouteId.Project]: projectId }}>
      {({ data, error, loading }: QueryResult) => {
        // ... processing data into fooList ...
        return props.children({ data: fooList, error, loading });
      }}
    </Query>
  );
}

并像使用它一样

  <Grid item xs={12}>
    <QueryFoos {...requiredProps}>
      {({ data, error, loading }) =>
        loading ? <div>Loading</div>
        : error ? <div>{error}</div>
        : <EntityTable entities={listFoos} />}
    </QueryFoos>
  </Grid>

这很清楚。


推荐阅读