如何使用 Relay 容器、react-router 和 GraphQL 按 id 获取和显示项目

Posted

技术标签:

【中文标题】如何使用 Relay 容器、react-router 和 GraphQL 按 id 获取和显示项目【英文标题】:How to fetch and display item by id using Relay container, react-router and GraphQL 【发布时间】:2017-01-23 03:15:56 【问题描述】:

我很难理解中继路由、react-router 参数以及构建查询和容器!

我想在用户单击 FeatureList 中的特定功能时编辑功能。它传递了一个名为“id”的参数,它是 Route.js 中 Feature 的 id

  <Route path='/' component=AppComponent queries=ViewerQuery>
    <IndexRoute component=FeaturesContainer queries=ViewerQuery />
    <Route path='/feature' component=FeatureComponent queries=ViewerQuery />
    <Route path="/feature/edit/:id" component=FeatureEditComponent queries=FeatureQuery/>
    <Redirect from='*' to='/' />
  </Route>

在我的 FeatureQuery 文件中,我有以下查询:

export default 
  viewer: (Component) => Relay.QL`
    query 
      viewer 
        $Component.getFragment('viewer')
      
    
  `
;

此时我完全陷入困境。如何扩展它以包含“id”并使用“id”查询功能? 相关的中继容器片段会是什么形状?我只看到深入一层的例子。

我试过了,但我知道这是不对的:

export default 
    feature: (Component) => Relay.QL`
        query 
            viewer 
                features(id:$id) 
                  $Component.getFragment('feature')
                
            
        
    `
;

这是获取功能列表的当前中继容器,如何修改它以仅通过 id 返回 1 个功能? :

export default Relay.createContainer(CreativeEditComponent, 
  fragments: 
    viewer: () => Relay.QL`
        fragment on User 
        id,
        features(first: 20) 
          edges 
            node 
              id
              name
              description

            
          
        
      `
  
);

我在 GraphiQL 中测试了一个查询,它按预期工作:

query 
  viewer 
    features(id:"1") 
      edges 
        node 
          id
          name
          description
         
      
     
  

结果:


  "data": 
    "viewer": 
      "features": 
        "edges": [
          
            "node": 
              "id": "Q3JlYXRpdmU6MQ==",
              "name": "React",
              "description": "A javascript library for building user interfaces."
            
          
        ]
      
    
  

schema.js:

const userType = new GraphQLObjectType(
  name: 'User',
  description: 'A person who uses our app',
  fields: () => (
    id: globalIdField('User'),

    features: 
      type: featureConnection,
      description: 'Features that I have',
      //args: connectionArgs,

      args: 
        id: 
          type: GraphQLString,
        ,
        after: 
          type: GraphQLString,
        ,
        first: 
          type: GraphQLInt,
        ,
        before: 
          type: GraphQLString,
        ,
        last: 
          type: GraphQLInt,
        ,
      ,

      resolve: (_, args) => 
        return resolveGetFeatures(args)
      ,
    ,


  ),
  interfaces: [nodeInterface]
);



const featureType = new GraphQLObjectType(
  name: 'Feature',
  description: 'Feature integrated in our starter kit',
  fields: () => (
    id: globalIdField('Feature'),
    name: 
      type: GraphQLString,
      description: 'Name of the feature'
    ,
    description: 
      type: GraphQLString,
      description: 'Description of the feature'
    
  ),
  interfaces: [nodeInterface]
);

【问题讨论】:

【参考方案1】:

您需要将路由器变量传递给您的片段。

const ViewerQuery = 
  viewer: (Component, vars) => Relay.QL`
    query 
      viewer 
        $Component.getFragment('viewer', vars) # <-- this
      
    
  `

我从这里复制了这个代码细节:https://github.com/relay-tools/react-router-relay/issues/92#issuecomment-235641397

然后你可以在你的组件中使用 id 变量,但是你需要一个 id 的初始值:

export default Relay.createContainer(CreativeEditComponent, 
  initialVariables: 
    id: ''
  ,
  fragments: 
    viewer: () => Relay.QL`
        fragment on User 
          id,
          feature(id:$id) 
            id
            name
            description
          
        `
    
);

并且在 schema.js 中为您的用户类型定义一个字段,该字段仅提供一个功能:

const userType = new GraphQLObjectType(
  name: 'User',
  description: 'A person who uses our app',
  fields: () => (
    id: globalIdField('User'),
    feature: 
      type: featureType,
      description: 'feature',
      args: 
        id: 
          type: GraphQLString,
          description: 'The id of the feature'
        
      ,
      resolve: (_, args) => resolveGetFeature (args),
    ,
    ...

【讨论】:

以上是关于如何使用 Relay 容器、react-router 和 GraphQL 按 id 获取和显示项目的主要内容,如果未能解决你的问题,请参考以下文章

将 react-router 和 react-router-relay 从 v1.x 更新到 v2.x(位置“/”不匹配任何路由)

使用 Relay 和 React-Native 时的条件片段或嵌入的根容器

如何在 Relay Container 之间传递变量

使用 react-router-relay 访问要在查询中使用的 url 参数

使用 react-router 从 this.props.children 访问 React 组件

使用 Jest 对 Relay 容器的集成测试与工作中的 GraphQL 后端不工作