使用 Apollo Client 为 React 组件动态设置 GraphQL 查询
Dynamically set GraphQL queries for React components with Apollo Client
我正在构建一个 React 前端,它允许用户从静态查询列表中 select 查询 "active" 并将结果展平到 table 中显示.将 GraphQL 查询从高阶组件传递到嵌套子组件的最佳方式是什么?
我见过的大多数 documentation/solutions 都集中在将静态查询与从组件状态到组件的动态条件绑定在一起,这对我来说不起作用,因为不同的静态查询具有不同的字段和查询不同的节点类型。
这里的 best-practice/recommended 方法是什么?我觉得这不是一个非常独特的用例,但我似乎找不到任何可以做类似事情的例子。
我正在使用 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
};
}
让我们以以下组件为例:
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);
包装起来很容易
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,
};
创建ProfileWithData.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,我会修复它。
我正在构建一个 React 前端,它允许用户从静态查询列表中 select 查询 "active" 并将结果展平到 table 中显示.将 GraphQL 查询从高阶组件传递到嵌套子组件的最佳方式是什么?
我见过的大多数 documentation/solutions 都集中在将静态查询与从组件状态到组件的动态条件绑定在一起,这对我来说不起作用,因为不同的静态查询具有不同的字段和查询不同的节点类型。
这里的 best-practice/recommended 方法是什么?我觉得这不是一个非常独特的用例,但我似乎找不到任何可以做类似事情的例子。
我正在使用 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
};
}
让我们以以下组件为例:
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);
包装起来很容易
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,
};
创建ProfileWithData.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,我会修复它。