#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('');
}
}