私のような突然変異があります
mutation deleteRecord($id: ID) {
deleteRecord(id: $id) {
id
}
}
別の場所に要素のリストがあります。
サーバーから戻ることができるものがありますか?リストを更新するにはどうすればよいですか?
より一般的には、apollo/graphqlで削除を処理するためのベストプラクティスは何ですか?
グッドプラクティススタイルかどうかはわかりませんが、updateQueriesを使用してreact-apolloでアイテムの削除を処理する方法は次のとおりです。
import { graphql, compose } from 'react-apollo';
import gql from 'graphql-tag';
import update from 'react-addons-update';
import _ from 'underscore';
const SceneCollectionsQuery = gql `
query SceneCollections {
myScenes: selectedScenes (excludeOwner: false, first: 24) {
edges {
node {
...SceneCollectionScene
}
}
}
}`;
const DeleteSceneMutation = gql `
mutation DeleteScene($sceneId: String!) {
deleteScene(sceneId: $sceneId) {
ok
scene {
id
active
}
}
}`;
const SceneModifierWithStateAndData = compose(
...,
graphql(DeleteSceneMutation, {
props: ({ mutate }) => ({
deleteScene: (sceneId) => mutate({
variables: { sceneId },
updateQueries: {
SceneCollections: (prev, { mutationResult }) => {
const myScenesList = prev.myScenes.edges.map((item) => item.node);
const deleteIndex = _.findIndex(myScenesList, (item) => item.id === sceneId);
if (deleteIndex < 0) {
return prev;
}
return update(prev, {
myScenes: {
edges: {
$splice: [[deleteIndex, 1]]
}
}
});
}
}
})
})
})
)(SceneModifierWithState);
以下は、underscore.jsなしで機能する同様のソリューションです。バージョン2.1.1のreact-apollo
でテストされています。削除ボタンのコンポーネントを作成します。
import React from "react";
import { Mutation } from "react-apollo";
const GET_TODOS = gql`
{
allTodos {
id
name
}
}
`;
const DELETE_TODO = gql`
mutation deleteTodo(
$id: ID!
) {
deleteTodo(
id: $id
) {
id
}
}
`;
const DeleteTodo = ({id}) => {
return (
<Mutation
mutation={DELETE_TODO}
update={(cache, { data: { deleteTodo } }) => {
const { allTodos } = cache.readQuery({ query: GET_TODOS });
cache.writeQuery({
query: GET_TODOS,
data: { allTodos: allTodos.filter(e => e.id !== id)}
});
}}
>
{(deleteTodo, { data }) => (
<button
onClick={e => {
deleteTodo({
variables: {
id
}
});
}}
>Delete</button>
)}
</Mutation>
);
};
export default DeleteTodo;
個人的に、削除されたアイテムの数を表すint
を返します。次に、updateQueries
を使用して、キャッシュからドキュメントを削除します。
これらの答えはすべて、クエリ指向のキャッシュ管理を前提としています。
IDが_1
_のuser
を削除し、このユーザーがアプリ全体の20のクエリで参照された場合はどうなりますか?上記の答えを読んで、それらすべてのキャッシュを更新するコードを書かなければならないと仮定しなければなりません。これは、コードベースの長期的な保守性がひどく、リファクタリングが悪夢になります。
私の意見では、最良の解決策はapolloClient.removeItem({__typeName: "User", id: "1"})
のようなものです。
null
に置き換えます[User]
_リストでこのアイテムを除外しますしかし、それは存在しません(まだ)
それは素晴らしいアイデアかもしれませんし、もっと悪いかもしれません(例えば、ページネーションを壊すかもしれません)
それについての興味深い議論があります: https://github.com/apollographql/apollo-client/issues/899
これらの手動クエリの更新には注意します。最初は食欲をそそるように見えますが、アプリが成長する場合はそうではありません。少なくともその上に固体の抽象化レイヤーを作成します。例:
_
const MY_QUERY = gql``;
// it's local 'cleaner' - relatively easy to maintain as you can require proper cleaner updates during code review when query will change
export function removeUserFromMyQuery(apolloClient, userId) {
// clean here
}
_
そして、それらの更新をすべて収集し、最終更新でそれらをすべて呼び出します
_function handleUserDeleted(userId, client) {
removeUserFromMyQuery(userId, client)
removeUserFromSearchQuery(userId, client)
removeIdFrom20MoreQueries(userId, client)
}
_