Как удалить общий узел из двух разных ретрансляционных соединений?

#javascript #graphql #relay #relaymodern

Вопрос:

Я работаю над созданием простого приложения Relay/GraphQL с использованием узла.

На корневом уровне у меня есть соединение под названием «заметки», которое разбивает на страницы все заметки в базе данных. В моем объекте пользователя у меня есть подключение notes, которое разбивает на страницы все заметки, созданные пользователем.

   const rootNotesId = ConnectionHandler.getConnectionID('client:root', 'RootNotesConnection_notes');
  const userNotesId = ConnectionHandler.getConnectionID(queryData?.me?.id, 'UserNotesConnection_notes');
  
  const rootNotes = usePaginationFragment(graphql `
    fragment NotesRoot_notes on Query @refetchable(queryName: "NotesRootQuery") {
      notes(first: $count, after: $cursor) @connection(key: "RootNotesConnection_notes") {
        edges {
          node {
            ...Note_note
          }
        }
      }
    }
  `, queryData);
  
  const userNotes = usePaginationFragment(graphql`
    fragment NotesUser_notes on Query @refetchable(queryName: "NotesUserQuery") {
      me {
        id
        notes(first: $count, after: $cursor) @connection(key: "UserNotesConnection_notes") {
          edges {
            node {
              ...Note_note
            }
          }
        }
      }
    }
  `, queryData);
 

Как добавить или удалить заметку для обоих подключений одновременно на стороне клиента? У меня есть два разных типа ребер, и я думал, что этот код будет работать:

   const [commit, isInFlight] = useMutation(graphql `
    mutation NotesCreateMutation($input: createNoteInput!) {
      createNote(input: $input) {
        noteEdge {
          cursor,
          node {
            id
            user {
              username
            }
            content
          }
        }
      }
    }
  `);
  
  const handleButtonClick = () => {
    if (!isInFlight) {
      commit({
        variables: {
          input: {
            content: newNoteInput
          }
        },
        updater: store => {
          const rootCon = ConnectionHandler.getConnection(store.get('client:root'), 'RootNotesConnection_notes');
          const userCon = ConnectionHandler.getConnection(store.get(userId), 'UserNotesConnection_notes');
          const payload = store.getRootField('createNote');
          const newEdge = payload.getLinkedRecord('noteEdge');
          const newNote = newEdge.getLinkedRecord('node');
          debugger;
          const newRootEdge = ConnectionHandler.createEdge(store, rootCon, newNote, 'QueryNotesEdge');
          const newUserEdge = ConnectionHandler.createEdge(store, userCon, newNote, 'UserNotesEdge');
          ConnectionHandler.insertEdgeAfter(rootCon, newRootEdge);
          ConnectionHandler.insertEdgeAfter(userCon, newUserEdge);
        }
      });
      setNewNoteInput('');
    }
  }
 

Единственное, что я могу найти в своей отладке, — это то, что курсор никогда не устанавливается для нового края. Прохождение этого кода в отладчике показывает, что все переменные перед newRootEdge разрешением просто отлично

Ответ №1:

Это сработало. Благодаря этой теме для хорошего обходного пути: https://github.com/facebook/relay/issues/2761

 const handleButtonClick = () => {
    if (!isInFlight) {
      commit({
        variables: {
          input: {
            content: newNoteInput
          }
        },
        updater: store => {
          const rootCon = ConnectionHandler.getConnection(store.get('client:root'), 'RootNotesConnection_notes');
          const payload = store.getRootField('createNote');
          const newRootEdge = payload.getLinkedRecord('noteEdge');
          const prevRootEdges = rootCon.getLinkedRecords('edges');
          const nextRootEdges = [...prevRootEdges, newRootEdge];
          rootCon.setLinkedRecords(nextRootEdges, 'edges');
          
          const userCon = ConnectionHandler.getConnection(store.get(userId), 'UserNotesConnection_notes');
          const newNote = newRootEdge.getLinkedRecord('node');
          const newUserEdge = ConnectionHandler.createEdge(store, userCon, newNote, 'UserNotesEdge');
          newUserEdge.setValue(newRootEdge.getValue('cursor'), 'cursor');
          const prevUserEdges = userCon.getLinkedRecords('edges');
          const nextUserEdges = [...prevUserEdges, newUserEdge];
          userCon.setLinkedRecords(nextUserEdges, 'edges');
        }
      });
      setNewNoteInput('');
    }
  }