如何:在 GraphQL 中增加基于整数的字段的值

Posted

技术标签:

【中文标题】如何:在 GraphQL 中增加基于整数的字段的值【英文标题】:HowTo: Increment the value of an integer based field in GraphQL 【发布时间】:2017-08-22 14:39:29 【问题描述】:

所以,我希望在 GraphCool 中创建一个 GraphQL 突变,它将整数字段的现有值增加预定量,作为变量传入。例如:

mutation updateLikes ($id: ID!, $count: Int) 
  updatePosts (id: $id, likes: incrementBy $count) 
    id
    likes
  


Query variable


  "id" : "cj0qkl04vep8k0177tky596og",
  "count": 1

我该怎么做?

另外,我正在尝试从 onClick 事件触发上述过程,但收到“无法读取 null 的属性 'props'”错误消息,我怀疑 this.props.client.query:

Photo.js

import React from 'react';
import Comments from './Comments';
import CSSTransitionGroup from 'react-addons-css-transition-group';
import  Link  from 'react-router';
import 
  gql,
  graphql,
  withApollo
 from 'react-apollo';
import ApolloClient from 'apollo-client';

class Photo extends React.Component 

  incrementQuery(currentID) 
    console.log("like of id=" + currentID+ " has been incremented by 1");

    this.props.client.query(
      query: gql`
        mutation updatePosts($id: ID!) 
          updatePosts (id: $id, likes: 1) 
            id
            likes
          
          
      `,
      variables: 
        id: currentID,
      ,
    );
  

  render() 
    const  post, i  = this.props;

    return (
      <figure key=i className="grid-figure">

        <div className='grid-photo-wrap'>
          <Link to=`/view/$post.id`>
            <img className='grid-photo' src=post.displaysrc alt=post.caption />
          </Link>

          <CSSTransitionGroup transitionName="like" transitionEnterTimeout=500 transitionLeaveTimeout=500>
            <span key=post.likes className="likes-heart">post.likes</span>
          </CSSTransitionGroup>

        </div>

        <figcaption>
          <p>post.caption</p>

          <div className="control-buttons">
            <button onClick=this.incrementQuery.bind(null,i) className="likes">&hearts; post.likes</button>

            <Link to=`/view/$post.id` className="button">
              <span className="comment-count">
                <span className="speech-bubble"></span> (post.comments ? Object.keys(post.comments).length : 0)
              </span>
            </Link>
          </div>

        </figcaption>

      </figure>
    )
  
;

Photo.PropTypes = 
  client: React.PropTypes.instanceOf(ApolloClient).isRequired,
  query: React.PropTypes.object,
  variables: React.PropTypes.object,
  data: React.PropTypes.shape(
    loading: React.PropTypes.bool.isRequired,
    error: React.PropTypes.bool.isRequired,
    updatePosts: React.PropTypes.object,
  ).isRequired,


const PhotoWithApollo = withApollo(Photo);

export default PhotoWithApollo;

抛出的错误如下:

Uncaught TypeError: Cannot read property 'props' of null
    at incrementQuery (http://localhost:7770/static/bundle.js:56347:12)
    at proxiedMethod (http://localhost:7770/static/bundle.js:54898:31)
    at htmlUnknownElement.wrapped (http://localhost:7770/static/bundle.js:47347:30)
    at Object.ReactErrorUtils.invokeGuardedCallback (http://localhost:7770/static/bundle.js:6346:17)
    at executeDispatch (http://localhost:7770/static/bundle.js:6146:22)
    at Object.executeDispatchesInOrder (http://localhost:7770/static/bundle.js:6169:6)
    at executeDispatchesAndRelease (http://localhost:7770/static/bundle.js:5599:23)
    at executeDispatchesAndReleaseTopLevel (http://localhost:7770/static/bundle.js:5610:11)
    at Array.forEach (native)
    at forEachAccumulated (http://localhost:7770/static/bundle.js:6446:10)
    at Object.processEventQueue (http://localhost:7770/static/bundle.js:5815:8)
    at runEventQueueInBatch (http://localhost:7770/static/bundle.js:6475:19)
    at Object.handleTopLevel [as _handleTopLevel] (http://localhost:7770/static/bundle.js:6491:6)
    at handleTopLevelWithoutPath (http://localhost:7770/static/bundle.js:16697:25)
    at handleTopLevelImpl (http://localhost:7770/static/bundle.js:16677:4)
    at ReactDefaultBatchingStrategyTransaction.perform (http://localhost:7770/static/bundle.js:8643:21)
    at Object.batchedUpdates (http://localhost:7770/static/bundle.js:12680:20)
    at Object.batchedUpdates (http://localhost:7770/static/bundle.js:8148:21)
    at dispatchEvent (http://localhost:7770/static/bundle.js:16808:21)
    at HTMLDocument.wrapped (http://localhost:7770/static/bundle.js:47347:30)

【问题讨论】:

【参考方案1】:

目前需要先查询值:

query Post($id: ID!) 
  Post (id: $id) 
    id
    likes
  

然后增加 likes 客户端并使用 likes 的新值更新帖子:

mutation updateLikes ($id: ID!, $likes: Int!) 
  updatePost (id: $id, likes: $likes) 
    id
    likes
  

通过一个特殊的数字增加喜欢是custom mutation 的一个很好的用例,我们已经在努力。

【讨论】:

非常感谢您的回复。我实际上是在尝试从 onClick 事件触发此过程,请查看我更新的问题,但我收到了一个空道具错误。我忽略了什么,这是最好的方法吗? 你在哪里设置组件的props?错误在哪里抛出? 针对 'this.props.client.query(',我在 Photo,js 的底部指定了 Photo.PropTypes,在我刚刚收到的错误消息上方生成了抛出的错误列出。 看起来 this 没有正确绑定到 incrementQuery 进一步考虑,当前解决方案的唯一问题是检索当前点赞快照、在客户端更新它、然后使用新值更新 Posts 之间的间隔,而其他用户可能拥有已经更新了“他们的”当前喜欢的快照,因此使当前正在更新的喜欢的内容完全不正确。是否有自定义查询/突变的 eta?【参考方案2】:

是的。这是一个非常有趣的问题。实际上,Apollo 客户端使用相同的方法来处理分页。您必须获取当前页面,当您转到页面底部时, (prev page+1)=>(next page) 是获取下一页的新页面变量内容,然后连接到上一页。不喜欢/喜欢,同样的方法,唯一的区别不需要连接到上一个堤/喜欢。代替它。

【讨论】:

以上是关于如何:在 GraphQL 中增加基于整数的字段的值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用`django-filters`编写将在整数字段上使用范围过滤器的GraphQL查询?

GraphQL 如何在子字段级别启用基于 ID 的查询?

如何对graphQL中的字段进行运行时数据操作?

如何在解析字段之前膨胀 GraphQL 项目?

在graphql中为用户类型中的字段编写字段级解析器

graphql 基于角色的授权