删除时出现中继错误:RelayMutationQuery:胖查询上的字段名称无效

Relay Error when deleting: RelayMutationQuery: Invalid field name on fat query

当我尝试提交删除突变时,我 运行 遇到了问题。当我提交时,我收到错误 Uncaught Invariant Violation: RelayMutationQuery: Invalid field name on fat query, `company`.。查看、创建和更新节点都可以。出于某种原因,我就是无法删除。它在 fatQuery 中提到了公司字段,但我在胖查询中唯一的字段是从服务器返回的 deletedUserId。提前致谢!

组件:

import React, {Component} from 'react';
import Relay from 'react-relay';
import {Link} from 'react-router';
import DeleteUserMutation from 'mutations/DeleteUserMutation';
import styles from './EmployeeItem.css';

class EmployeeItem extends Component {
  render() {
    const {user} = this.props;
    return (
      <div className={styles.employee}>
        <p><strong>ID:</strong> {user.id}</p>
        <p><strong>First Name:</strong> {user.firstName}</p>
        <p><strong>Last Name:</strong> {user.lastName}</p>
        <p><strong>Email:</strong> {user.email}</p>
        <div className="btn-group">
          <Link to={`/company/employees/${user.id}`} className="btn btn-primary">View Employee</Link>
          <button onClick={this.handleRemove} className="btn btn-danger">Delete User</button>
        </div>
      </div>
    )
  }

  handleRemove = (e) => {
    e.preventDefault();
    const {user, company} = this.props;

    Relay.Store.commitUpdate(new DeleteUserMutation({user, company}));
  };
}

export default Relay.createContainer(EmployeeItem, {
  fragments: {
    company: () => Relay.QL`
      fragment on Company {
        id
        ${DeleteUserMutation.getFragment('company')}
      }
    `,
    user: () => Relay.QL`
      fragment on User {
        id
        firstName
        lastName
        email
        ${DeleteUserMutation.getFragment('user')}
      }
    `
  }
});

突变:

import React from 'react';
import Relay from 'react-relay';

export default class DeleteUserMutation extends Relay.Mutation {
  static fragments = {
    company: () => Relay.QL`
      fragment on Company {
        id
      }
    `,
    user: () => Relay.QL`
      fragment on User {
        id
      }
    `
  };

  getMutation() {
    return Relay.QL`mutation {deleteUser}`;
  }

  getFatQuery() {
    return Relay.QL`
      fragment on DeleteUserPayload {
        deletedUserId
      }
    `;
  }

  getVariables() {
    return {
      id: this.props.user.id,
    }
  }

  getConfigs() {
    return [{
      type: 'NODE_DELETE',
      parentName: 'company',
      parentID: this.props.company.id,
      connectionName: 'employees',
      deletedIDFieldName: 'deletedUserId'
    }]
  }

  // Wasn't sure if this was causing the error but it appears to be 
  // something else.
  // getOptimisticResponse() {
  //   return {
  //     deletedUserId: this.props.user.id
  //   }
  // }
}

此错误是指您在 getConfigs() 实施中引用了 "company"。 NODE_DELETE 配置告诉 Relay 如何通过将存储中的节点(例如 parentID)映射到胖查询上的字段(例如 parentName)来构造突变查询。

虽然您今天可能不一定需要它,但您应该在此处将 company 添加到突变负载和脂肪查询中,因为公司 受到此影响改变。更具体地说,正在修改公司的员工连接:)

NevilleS 的解决方案帮我解决了这个问题:

我向根字段添加了一个 globalId(在我的例子中是一个名为 "verify" 的对象)并且我还将我在服务器上的突变更改为 return 一个边缘,而不仅仅是底层类型.我还将根 "verify" 对象添加到变异输出字段:客户端的中继变异需要知道哪个对象拥有连接,将新边缘放在哪里是有意义的。

export const Verify = new GraphQLObjectType({
name: 'Verify',
fields: () => ({
  id: globalIdField('Verify'),
  verifications: {
    args: connectionArgs,
    type: VerificationConnection,
    resolve: (rootValue, args) => connectionFromArray(rootValue.verifications, args)
  },

将 "verify" 和 "verificationEdge" 添加到突变的输出字段。

export const AddVerifiedSchool = mutationWithClientMutationId({
name: 'AddVerifiedSchool',
inputFields: {
  verification: {
    type: VerifiedSchoolInput
  }
},
outputFields: {
  success: {
    type: GraphQLBoolean,
    resolve: () => true
  },
  verificationEdge: {
    type: VerificationEdge,
    resolve: ({verification, context}) => {
      console.log('verification', verification);
      return verification
    }
  },
  verify: {
    type: Verify,
    resolve: ({verification, context}) => {
      return context.rootValue
    }
  }
},

将验证字段添加到胖查询中,并将(验证中的globalId "id")添加到片段中,并使用新的globalId 来标识存在连接的节点。

static fragments = {
  verify: () => Relay.QL`fragment on Verify { id }`,
  action: () => Relay.QL`fragment on Action { name url }`
};

getConfigs() {
  return [{
    type: 'RANGE_ADD',
    parentName: 'verify',
    parentID: this.props.verify.id,
    connectionName: 'verifications',
    edgeName: 'verificationEdge',
    rangeBehaviors: {
      '': 'append'
    }
  }];
}

getFatQuery() {
  return Relay.QL`
  fragment on AddVerifiedSchoolPayload {
    verification {
      ${VerifiedSchool.getFragment('verification')}
    }
    verify {
      id
    }
  }`
}