ApolloClientにて、useMutation
でデータを更新した後にuseQuery
のデータを再取得する方法に関して
ざっと調べた結果です。
useQueryのrefetch関数を利用する。
useQuery
関数の戻り値に含まれるrefetch
関数を実行することで、データの再取得ができます。
useMutation
関数が同一コンポーネント内、もしくはすぐ配下のコンポーネントならば、
こちらの関数を利用すれば事足ります。
const { data, loading, error, refetch } = useQuery(ANY_GET_QUERY);
const [update, { loading, error }] = useMutation(ANY_SET_QUERY, {
onCompleted() {
refetch();
},
});
FETCHING DATA > Queries > Refetching - APOLLO DOCS
API > @apollo/react-hooks > useQuery > Result
useMutationのrefetchQueriesオプションを利用する。
いくつかのWidgetを組み合わせた構成の画面などで、兄弟関係のコンポーネントのQueryをRefetchさせたい場合は、
useMutation
関数のオプション引数refetchQueries
が便利です。
更新したいクエリ名を配列で渡すと、Mutation完了後に該当Queryを実行してくれます。
更新対象の可能性があるクエリ名を最大数記載しても、該当コンポーネントが無ければ
余分なクエリが実行されることはありません。
/**
* Widget A : リストの表示
*/
const QUERY_A = gql`
query QueryA {
list(id: $id) {
id
name
}
}
`;
const { data, loading, error } = useQuery(QUERY_A);
/**
* Widget B : リストの表示
*/
const QUERY_B = gql`
query QueryB($id: ID!) {
list(id: $id) {
id
date
}
}
`;
const { data, loading, error } = useQuery(QUERY_B);
/**
* Widget C : リストの更新
*/
const [update, { loading, error }] = useMutation(QUERY_B, {
refetchQueries: [
'QueryA',
'QueryB'
],
});
単にクエリ名を渡すのみの場合、クエリの引数は前回のものがそのまま活用されます。
名前文字列の代わりにvariables
を指定したオブジェクトを渡すことも可能です。
配列の代わりにuseMutation
の結果を受け取る関数を渡すこともできます。
const [update, { loading, error }] = useMutation(QUERY_B, {
refetchQueries: ( mutationResult ) => {
return [
'QueryA',
{
query: 'QueryB',
variables: { id: mutationResult.id }
}
]
},
});
Updating after a mutation - APOLLO DOCS
useMutation API > Options - APOLLO DOCS
react-hoc API > options.refetchQueries - APOLLO DOCS
onComplete関数が呼ばれない
refetch
されたいくつかのクエリのうち、onComplete
関数が呼ばれるものと呼ばれないものがありました。
今のところ原因は不明です。。。
useQuery
の戻り値のdata
はちゃんと新しくなっていたので、取り急ぎonComplete
を利用せず、
代わりにReactのuseMemo
を活用することで対処しました。
(情報求ム)
参考情報