Not getting payload after React-relay nested mutat

2019-07-14 16:47发布

This is a follow-up question to this answer posted earlier on SO about a react-relay mutation warning.

"In you case what you have to do is to add the FeatureLabelNameMutation getFragment to your AddCampaignFeatureLabelMutation query."

As with the OP in that question, I too want to make a nested relay mutation and I've tried doing what @Christine is suggesting, but I'm uncertain on where exactly to put the getFragment part.

In my application, I want to create a "task" with multiple nested "sub-tasks" when the user creates a task.

What I have tried works, but I don't get the returned PayLoad for the AddSubTaskMutation mutation. Here's what I've tried so far:

AddTaskMutation.js

export default class AddTaskMutation extends Relay.Mutation {
  static fragments = {
    classroom: () => Relay.QL`
      fragment on Classroom { 
        id,
        tasks(last: 1000) {
          edges {
            node {
                id,
                ${AddSubTaskMutation.getFragment('task')}, //<-- what I tried adding 
            },
          }
        },
      }`,
    }`,
  };
  ...

AddSubTaskMutation.js

export default class AddSubTaskMutation extends Relay.Mutation {
  static fragments = {
    task: () => Relay.QL`
      fragment on Task { 
        id,
      }`,
   };
   ...

TaskCreate.js

Relay.Store.update(
  new AddTaskMutation({
    title,
    instruction,
    start_date,
    end_date,
    published: isPublished,
    classroom: this.props.classroom
  }),
  {
    onSuccess: (response) => {
      let {taskEdge} = response.addTask;
      for (let subTask of this.state.subTaskContent) {
        Relay.Store.update(
          new AddSubTaskMutation({
            task: taskEdge.node,
            type: subTask['type'],
            position: subTask['position'],
            ...
          }),
        );
      }
    }
  }
)
...
export default Relay.createContainer(TaskCreate, {
  prepareVariables() {
    return {
      limit: Number.MAX_SAFE_INTEGER || 9007199254740991,
    };
  },
  fragments: {
    classroom: () => Relay.QL`
      fragment on Classroom {
        id,
        tasks(last: $limit) {
          edges {
            node {
              id,
              ...
            }   
          }
        },
        ...
        ${AddTaskMutation.getFragment('classroom')},
      }
    `,
  },
});

Apart from not getting the payload, I'm also getting the following warnings:

Warning: RelayMutation: Expected prop `task` supplied to `AddSubTaskMutation` to be data fetched by Relay. This is likely an error unless you are purposely passing in mock data that conforms to the shape of this mutation's fragment.
Warning: writeRelayUpdatePayload(): Expected response payload to include the newly created edge `subTaskEdge` and its `node` field. Did you forget to update the `RANGE_ADD` mutation config?

So my question is: where do i add the getFragment in AddTaskMutation.js to make this work?

1条回答
叛逆
2楼-- · 2019-07-14 17:13

From what I can tell, the issue is that you don't really understand what the mutation "fragment" is for vs. the rest of the mutation properties (fat query & configs). The warning you are seeing is related to Relay noticing that the task prop you are giving it isn't from the AddSubtaskMutation fragment, it's from the AddTaskMutation mutation query. But that's really just a red herring; your issue is that you don't need those fragments at all, you just need to configure the mutation appropriately to create your new nodes & edges. Here's a couple suggestions.

Step #1

  • Get rid of the fragments in both AddTaskMutation and AddSubtaskMutation, they seem unnecessary
  • Modify AddTaskMutation's constructor to take a bunch of fields for the task and a classroomID to specify the affected classroom
  • Similarly, modify AddSubTaskMutation to take a bunch of fields for the subtask and a taskID to specify the parent task
  • Make sure your AddTaskMutation payload includes the modified classroom and the new task edge
  • Define a RANGE_ADD mutation using the classroomID to target the classroom for the new task
  • Define a FIELDS_CHANGE mutation on AddSubtaskMutation that mutates the parent using the given taskID (I'm not sure how you're storing subtasks, probably a connection). You can change this to a RANGE_ADD if you really want.

Step #2: Simplify

  • It seems unnecessary to do this in 1+N mutations (N subtasks), when you seem to have all the information at the start. I'd modify the input of AddTaskMutation to accept a new task and an array of subtasks, and do it all at once...
查看更多
登录 后发表回答