如何乐观响应中继现代突变中的连接属性?

Posted

技术标签:

【中文标题】如何乐观响应中继现代突变中的连接属性?【英文标题】:how to optimisticResponse a connection property in relay modern mutation? 【发布时间】:2019-11-22 04:52:08 【问题描述】:

我在突变中有一个 cmets 连接,这是查询:

    export default mutationFromQuery(graphql`
  mutation AddBookMutation($input: AddBookInput! $count: Int $cursor: String ) 
    addBook(input: $input) 
      book 
        __typename
        cursor
        node 
          id
          title
          owner
          createdAt
          comments(first: $count, after: $cursor)
          @connection(key: "BookComments_comments", filters: []) 
            __typename
            edges  
              node  
                id
              
            
          
        
      
    
  
`)

这就是我的optimisticUpdater 不工作的方式:

optimisticUpdater: (store) => 
  const userProxy = store.get(viewerId)
  const owner = userProxy.getValue('username')
  const id = uuidv1();
  const book = store.create(id, 'Book');
  book.setValue(id, 'id');
  book.setValue(bookTitle, 'title');
  book.setValue(owner, 'owner');
  book.setValue(Date.now(), 'createdAt');
  const comments = store.create(uuidv1(), 'comments')
  comments.setLinkedRecords([], 'edges')
  const pageInfo = store.create(uuidv1(), 'pageInfo')
  pageInfo.setValue(null, 'endCursor')
  pageInfo.setValue(false, 'hasNextPage')
  pageInfo.setValue(false, 'hasPreviousPage')
  pageInfo.setValue(null, 'startCursor')
  comments.setLinkedRecord(pageInfo, 'pageInfo')
  book.setLinkedRecord(comments, 'comments')
  const bookEdge = store.create(uuidv1(), 'BookEdge');
  bookEdge.setLinkedRecord(book, 'node');
  console.log('bookEdge ', bookEdge)
  booksUpdater(userProxy, bookEdge);
,

我遇到的问题是 cmets 总是以 undefined 结束,正如您在上面看到的那样,我已经设置了它。我也这样做了,但我仍然没有得到一个乐观的 UI:

    optimisticResponse: 
      addBook: 
        book: 
          __typename: 'BookEdge',
          cursor: uuidv1(),
          node: 
            id: uuidv1(),
            title: bookTitle,
            owner: username,
            createdAt: Date.now(),
            comments: 
              __typename: 'CommentConnection',
              edges: [],
              pageInfo: 
                endCursor: null,
                hasNextPage: false
              
            
          
        
      
    ,

App 不会因optimisticResponse 代码而崩溃,但没有乐观的 UI 效果,但在使用未定义 cmets 的情况下,optimisticUpdater 会崩溃,现在我正在使用我的更新程序:

updater: (store) => 
   const userProxy = store.get(viewerId)
   const payload = store.getRootField('addBook');
   booksUpdater(userProxy, payload.getLinkedRecord('book'));
,

由于 cmets 未定义,我想我们不能将其用于乐观效果:

  const comments = store.create(uuidv1(), 'comments')
  comments.setLinkedRecords([], 'edges')
  book.setLinkedRecord(comments, 'comments')

在我的书上,这是一个查询,它的 cmets 片段在使用上面的代码进行乐观更新时未定义:

export default createRefetchContainer(
  BookItem,
  
    book: graphql`
      fragment BookItem_book on Book
        @argumentDefinitions(
          count:  type: "Int", defaultValue: 5 
          cursor:  type: "String", defaultValue: null 
        ) 
        id
        title
        owner
        createdAt
        ...BookComments_book  
      
    `
  ,
  graphql`
    query BookItemQuery($id: ID!, $count: Int, $cursor: String) 
      book: node(id: $id) 
        ...BookItem_book @arguments(count: $count, cursor: $cursor)
      
    
  `
);

现在获取 book.cmets.edges 的 cmets 组件的查询是未定义的:

export default createPaginationContainer(
  BookComments,
  
    book: graphql`
      fragment BookComments_book on Book 
      @argumentDefinitions(
        count:  type: "Int", defaultValue: 3 
        cursor:  type: "String", defaultValue: null 
      ) 
        id
        title
        comments(first: $count, after: $cursor)
          @connection(key: "BookComments_comments", filters: []) 
            __typename
          edges 
            node 
              id
              text
              owner
              createdAt
            
          
          pageInfo 
            startCursor
            endCursor
            hasPreviousPage
            hasNextPage
          
        
      
    `
  ,
  
    direction: 'forward',
    getConnectionFromProps: (props) => props.book && props.book.comments,
    getFragmentVariables: (prevVars, totalCount) => (
      ...prevVars,
      count: totalCount
    ),
    getVariables: (props,  count, cursor , _fragmentVariables) => (
      count,
      cursor,
      id: props.book.id
    ),
    query: graphql`
      query BookCommentsQuery($id: ID!, $count: Int, $cursor: String) 
        book: node(id: $id) 
          ...BookComments_book @arguments(count: $count, cursor: $cursor)
        
      
    `
  
);

也许这是一种反模式?但我只是想对此产生乐观的影响

【问题讨论】:

发布您的完整变异代码以及所有查询 @SibeliusSeraphini 我更新了问题,让 cmets 在optimisticUpdater 中未定义,这不起作用? => cmets.setLinkedRecords([], 'edges') 连接指令应该用在查询或片段中,而不是在突变中。请发布您用于获取将在组件中显示的数据的查询或片段代码(该查询可能在 QueryRenderer 或重新获取容器中使用) 我只是把它放在那里,因为我认为我已经尝试了所有方法,但对于该 cmets 嵌套连接的乐观没有任何作用,所以我只是与我的更新程序达成一致,您之前尝试过用于具有嵌套连接的节点的乐观 UI ? 我总是只处理组件中的空/未定义嵌套连接。我猜你想乐观地添加一些cmets,对吧?如果没有,那么处理空 cmets 并等待服务器发出真正的响应会更容易。 【参考方案1】:

对于这些组件和查询如何工作,我仍然不太清楚,所以我稍后会更新这个答案。 (我不知道您是想从 node() 查询中乐观地返回新书还是将其添加到某些书籍列表/连接中)

请检查我是否使用了正确的类型名称(CommentConnection / CommentsConnection 等)

optimisticUpdater: (store) => 
  const userProxy = store.get(viewerId)
  const owner = userProxy.getValue('username')
  const commentsParams =   // must be same keys and values as in comments(first: $count, after: $cursor)
    first: count,
    after: cursor
  

  // Create Book
  const id = uuidv1();
  const book = store.create(id, 'Book');
  book.setValue(id, 'id');
  book.setValue(bookTitle, 'title');
  book.setValue(owner, 'owner');
  book.setValue(Date.now(), 'createdAt');

  // Create comments connection
  const comments = store.create(uuidv1(), 'CommentConnection')
  comments.setLinkedRecords([], 'edges')

  // Create PageInfo
  const pageInfo = store.create(uuidv1(), 'PageInfo')
  pageInfo.setValue(null, 'endCursor')
  pageInfo.setValue(false, 'hasNextPage')
  pageInfo.setValue(false, 'hasPreviousPage')
  pageInfo.setValue(null, 'startCursor')

  // Link created records
  comments.setLinkedRecord(pageInfo, 'pageInfo')
  book.setLinkedRecord(comments, 'comments', commentsParams) // don't forget commentsParams with same values as are used in comments graphql query

  // I'm not sure about this final part, because I don't really get how that app works, but if you want this book to show as optimistic response for `node(id: $id)`, you'll do something like this:
  store.getRoot().setLinkedRecord(book, 'node',  id: id ) // same id as used in BookItemQuery

【讨论】:

我不知道有参数设置记录,我在文档上挖掘它并自己尝试了很多东西,仍然没有任何效果,也许你尝试过在嵌套连接中进行突变?我正在考虑查看您的代码并找出答案

以上是关于如何乐观响应中继现代突变中的连接属性?的主要内容,如果未能解决你的问题,请参考以下文章

中继现代突变,RANGE_ADD / Append

使用后续突变和缺失片段中继 commitUpdate 回调

进行后续突变后中继不更新

Apollo 客户端递归突变

如何删除 Graphene Django 突变查询(中继)中的嵌套输入对象?

将状态传递给中继中的 getVaribles 突变