中继棱镜 graphql 更新存储

Posted

技术标签:

【中文标题】中继棱镜 graphql 更新存储【英文标题】:relay prisma graphql update store 【发布时间】:2019-05-08 18:22:21 【问题描述】:

我正在尝试让棱镜和继电器工作。这是我的仓库:

https://github.com/jamesmbowler/prisma-relay-todo

这是一个简单的待办事项列表。我可以添加待办事项,但 ui 没有更新。当我刷新时,待办事项就在那里。

我能找到的所有更新商店的示例都对正在更新/创建的对象使用“父级”。

见https://facebook.github.io/relay/docs/en/mutations.html#using-updater-and-optimisticupdater

此外,“更新程序配置”还需要一个“父 ID”。 https://facebook.github.io/relay/docs/en/mutations.html#updater-configs

来自 relay-runtime 的 RelayConnectionHandler.js 评论: https://github.com/facebook/relay/blob/master/packages/relay-runtime/handlers/connection/RelayConnectionHandler.js#L232

 * store => 
 *   const user = store.get('<id>');
 *   const friends = RelayConnectionHandler.getConnection(user, 'FriendsFragment_friends');
 *   const edge = store.create('<edge-id>', 'FriendsEdge');
 *   RelayConnectionHandler.insertEdgeAfter(friends, edge);
 * 

是否可以在没有“父级”的情况下更新商店?我只有待办事项,没有父母。

再次,创建记录有效,并给出以下响应:

“数据”: “创建待办事项”: “id”:“cjpdbivhc00050903ud6bkl3x”, “名称”:“测试”, “完成”:假

这是我的更新函数

updater: store => 
          const payload = store.getRootField('createTodo');

          const conn = ConnectionHandler.getConnection(store.get(payload.getDataID()), 'Todos_todoesConnection');

          ConnectionHandler.insertEdgeAfter(conn, payload, cursor);

,

我做了一个console.log(conn),它是未定义的。

请帮忙。

----编辑---- 感谢 Denis,我认为解决了一个问题 - ConnectionHandler 的问题。

但是,我仍然无法更新 ui。这是我在更新程序功能中尝试过的:

const payload = store.getRootField('createTodo');
const clientRoot = store.get('client:root');
const conn = ConnectionHandler.getConnection(clientRoot, 'Todos_todoesConnection');
ConnectionHandler.createEdge(store, conn, payload, 'TodoEdge');

我也试过这个:

const payload = store.getRootField('createTodo');
const clientRoot = store.get('client:root');
const conn = ConnectionHandler.getConnection(clientRoot, 'Todos_todoesConnection');
ConnectionHandler.insertEdgeAfter(conn, payload);

我的数据形状与他们的示例不同,因为我的返回数据中没有“todoEdge”和“节点”(见上文)。

tod​​oEdge 光标 节点 完全的 ID 文本

我如何像这样获得LinkedRecord?

const newEdge = payload.getLinkedRecord('todoEdge');

【问题讨论】:

谁是父母?是query 还是您的架构的任何其他类型? 架构如下:github.com/jamesmbowler/prisma-relay-todo/blob/… - 是的,我相信查询是父级。 【参考方案1】:

如果query 是父级,则parentID 将是client:root

看看这个:https://github.com/facebook/relay/blob/1d72862fa620a9db69d6219d5aa562054d9b93c7/packages/react-relay/classic/store/RelayStoreConstants.js#L18

也在这个问题上:https://github.com/facebook/relay/issues/2157#issuecomment-385009482

创建一个const ROOT_ID = 'client:root'; 并将ROOT_ID 传递为您的parentID。此外,请检查更新程序上的连接名称,它必须与您声明查询的名称完全相同。

更新: 其实你可以导入ROOT_ID of relay-runtime

import ROOT_ID from 'relay-runtime';

更新 2

您的编辑对我来说不是很清楚,但我会为您提供一个示例,应该可以吗?运行突变后,您首先使用getRootField 访问其数据,就像您正在做的那样。所以,如果我有这样的突变:

  mutation UserAddMutation($input: UserAddInput!) 
    UserAdd(input: $input) 
      userEdge 
        node 
          name
          id
          age
        
      
      error
    
  

你会做的:

const newEdge = store.getRootField('UserAdd').getLinkedRecord('userEdge');
      connectionUpdater(
        store,
        parentId: ROOT_ID,
        connectionName: 'UserAdd_users',
        edge: newEdge,
        before: true,
      );

这个connectionUpdater 是一个辅助函数,看起来像这样:

export function connectionUpdater( store, parentId, connectionName, edge, before, filters ) 
  if (edge) 
    if (!parentId) 
      // eslint-disable-next-line
      console.log('maybe you forgot to pass a parentId: ');
      return;
    

    const parentProxy = store.get(parentId);

    const connection = ConnectionHandler.getConnection(parentProxy, connectionName, filters);

    if (!connection) 
      // eslint-disable-next-line
      console.log('maybe this connection is not in relay store yet:', connectionName);
      return;
    

    const newEndCursorOffset = connection.getValue('endCursorOffset');
    connection.setValue(newEndCursorOffset + 1, 'endCursorOffset');

    const newCount = connection.getValue('count');
    connection.setValue(newCount + 1, 'count');

    if (before) 
      ConnectionHandler.insertEdgeBefore(connection, edge);
     else 
      ConnectionHandler.insertEdgeAfter(connection, edge);
    
  

希望对你有帮助:)

【讨论】:

谢谢你,丹尼斯!我想我解决了一个问题,但还有一个问题 - 请查看我的编辑。 这是我的变异返回的结果: "data" : "createTodo" : "id" : "cjpdbivhc00050903ud6bkl3x", "name" : "testing", "complete" : false 所以,我没有与您的示例等效的数据结构,所以我不能“getLinkedRecord”.. 为什么有这个data 字段?这有点奇怪。你不能让你在服务器上的突变只返回边缘吗?一个todoEdge 我正在使用 prisma,所以我不能轻易改变它。 prisma.io/client/client-javascript 哦,我明白了。我没有使用 Prisma 的经验,但我在您提供的链接上看到了一个运行我的示例的突变示例,Native GraphQL

以上是关于中继棱镜 graphql 更新存储的主要内容,如果未能解决你的问题,请参考以下文章

瑜伽graphql服务器+棱镜服务器:多租户

错误:“GraphQL 错误:无效版本:1.17”,同时部署到棱镜云 [关闭]

GraphQL,中继:处理错误

GraphQL 和中继过滤 UI

GraphQL + 中继连接优化

我对中继和graphql解析方法感到困惑