使用 Apollo Client 为 React 组件动态设置 GraphQL 查询
Posted
技术标签:
【中文标题】使用 Apollo Client 为 React 组件动态设置 GraphQL 查询【英文标题】:Dynamically set GraphQL queries for React components with Apollo Client 【发布时间】:2017-07-21 20:09:56 【问题描述】:我正在构建一个 React 前端,它允许用户从静态查询列表中选择一个“活动”查询,并将结果展平为要在表格中显示的结果。将 GraphQL 查询从高阶组件传递到嵌套子组件的最佳方法是什么?
我看到的大多数文档/解决方案都侧重于将静态查询与从组件状态到组件的动态条件绑定,这不适用于我的目的,因为不同的静态查询具有不同的字段并查询不同的节点类型.
这里的最佳实践/推荐方法是什么?我觉得这不是一个非常独特的用例,但我似乎找不到任何可以做类似事情的例子。
我使用 Apollo-Client/Redux 作为我的客户端存储。
下面是组件的大致轮廓:
class GridViewPage extends React.Component
constructor(props, context)
super(props, context);
this.state =
activeQuery = ... Stores the selected query ...
;
render()
return (
<div className="gridContainer">
...Component here allows users to select a query from the active list and saves it/it's ID/Index to the state...
<Panel collapsible>
...Some toolbar components...
</Panel>
...Component here displays the result of the query (Ideally by receiving the query or the result of as a prop?)...
</div>
);
GridViewPage.propTypes =
grids: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired
;
function mapStateToProps(state, ownProps)
return
// Receives list of available queries as a prop
grids: state.grids
;
【问题讨论】:
【参考方案1】:我们以下面的组件为例:
ProfileWithData.js
import React, Component, PropTypes from 'react';
import graphql from 'react-apollo';
import gql from 'graphql-tag';
class Profile extends Component ...
Profile.propTypes =
data: PropTypes.shape(
loading: PropTypes.bool.isRequired,
currentUser: PropTypes.object,
).isRequired,
;
// We use the gql tag to parse our query string into a query document
const CurrentUserForLayout = gql`
query CurrentUserForLayout
currentUser
login
avatar_url
`;
const ProfileWithData = graphql(CurrentUserForLayout)(Profile);
用higher order component 包装它会很容易:
Profile.js
import React, Component, PropTypes from 'react';
export class Profile extends Component ...
Profile.propTypes =
data: PropTypes.shape(
loading: PropTypes.bool.isRequired,
currentUser: PropTypes.object,
).isRequired,
;
createProfileWithData.js
import React, Component, PropTypes from 'react';
import graphql from 'react-apollo';
import Profile from './Profile'
export default function createProfileWithData(query) =>
return graphql(query)(Profile);
然后你会像这样使用它:
Page.js
import React, Component, PropTypes from 'react';
import gql from 'graphql-tag';
import createProfileWithData from './createProfileWithData';
class Page extends Component
renderProfileWithData()
const textQuery = this.props;
// Simplest way, though you can call gql as a function too
const graphQLQuery = gql`$textQuery`;
const profileWithDataType = createProfileWithData(graphQLQuery);
return (
<profileWithDataType />
);
render()
return (<div>
..
this.renderProfileWithData()
..
</div>)
Profile.propTypes =
textQuery: PropTypes.string.isRequired,
;
我想你明白了。
当然,您的个人资料不会收到props.data.currentUser
,而是props.data.*
,具体取决于根查询,您将根据内容进行适当处理。
注意:这是直接在 Stack Overflow 中编写的,所以如果您遇到任何问题 - lmk,我会修复它。
【讨论】:
谢谢!已经开始在项目中应用这种模式,我想我最终会让它发挥作用。我遇到的一个直接错误是const profileWithDataType = createProfileWithData(graphQLQuery);
正在返回一个函数类型,因此当嵌套在this.renderProfileWithData()
中时没有命中render()
function?这可能是我的代码的语法问题,但值得一提。
是的,这可能是 JSX 的问题。我总是忘记该语法是否有效。你也可以这样做:``` return React.createElement(profileWithDataType, ); ```我确定你现在已经解决了这个问题,所以更新会很好:)
嘿!实际上我最终跳过了 createProfileWithData.js 并直接在 Page.js 中将查询设置为页面,相当于graphql(query)(Profile)
并且它有效:)以上是关于使用 Apollo Client 为 React 组件动态设置 GraphQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
使用 React 钩子处理 graphQL 突变错误(useMutation + Apollo-client)
技术博客 | 使用 Apollo Client 快速构建一个支持 GraphQL 的 React App
如何在 Apollo Client React 中获取多个条件查询?
你如何动态控制 react apollo-client 查询启动?