目次
1. はじめに
RefineでWebアプリケーションを開発する際、新しいデータを作成する処理は避けて通れません。ブログ記事の投稿、商品の登録、ユーザー情報の追加など、データの新規作成は基本的な機能です。
この記事では、Refineで新規データを作成するためのuseCreateデータフックの使い方を、初心者の方にも分かりやすく解説します。具体的には、useCreateの基本的な使い方から、mutateとmutateAsyncという2つのメソッドの違いまで、実際のコード例を交えながら説明していきます。
Refineを使い始めたばかりの方、Reactの基礎知識はあるがRefineのデータフックについて詳しく知りたい方を対象にしています。この記事を読めば、useCreateを使った基本的なデータ作成処理を自分で実装できるようになるはずです。
(ちなみに私は、RefineはおろかReactでの開発も未経験の状態からスタートしました。)
2. そもそもRefineとは?
Refineは、管理画面やダッシュボードなど、データを扱うWebアプリケーションを素早く構築できるReactフレームワークです。通常、データの取得・作成・更新・削除(CRUD操作)を実装するには多くのコードが必要ですが、Refineはこれらの処理を簡単に実装できる仕組みを提供しています。
Refineの特徴はデータフックという仕組みです。データフックは、データベースやAPIとのやり取りを抽象化し、複雑な処理を数行のコードで実現できるようにします。例えば、データの取得にはuseList
、更新にはuseUpdate
、削除にはuseDelete
といったフックが用意されています。
今回紹介するuseCreateは、その名の通り「新しいデータを作成する」ための専用フックです。通常であれば、fetchやaxiosを使ってAPIリクエストを送り、ローディング状態の管理やエラーハンドリングを自分で実装する必要がありますが、useCreateを使えばこれらの処理がすべて自動化されます。
つまり、Refineとそのデータフックを使うことで、開発者はビジネスロジックに集中でき、煩雑な定型処理から解放されるというわけです。
Refineについてより詳しく知りたい方は、公式ドキュメントをご覧ください。
3. useCreateデータフック概要
useCreateは、新しいレコード(データ)を作成するためのフックです。Refineの<Refine />
コンポーネントに渡されたdataProviderのcreateメソッドをミューテーション関数として利用します。
ここで「ミューテーション」という用語が出てきましたが、これは「データを変更する関数」のことです。「ミューテーション(mutation)」は「変更」という意味なので、データベースの内容を変える操作をする関数と考えれば分かりやすいでしょう。
useCreateは、具体的には以下のような場面で使用します:
- ブログ記事の新規投稿
- ECサイトでの商品登録
- ユーザー情報の追加
- お問い合わせフォームの送信
これらの「新しいデータを作る」処理すべてに、useCreateを活用できます。通常であればAPIエンドポイントへのPOSTリクエスト、レスポンスの処理、エラーハンドリング、ローディング状態の管理など、多くのコードを書く必要がありますが、useCreateはこれらをすべて内部で処理してくれます。
4. useCreateの主な特徴
useCreateには、データ作成処理を効率的に行うための5つの主な特徴があります。
新規作成操作
mutate
メソッドを使って新しいデータを作成できます。resource
(リソース名)とvalues
(作成するデータ)を指定するだけで、データの作成処理が実行されます。
状態管理
mutation
オブジェクトを通じて、ローディング状態やエラー、レスポンスデータなど、TanStack Query(Reactでデータ取得や状態管理を簡単にするライブラリ)のuseMutation
の全ての返り値にアクセスできます。これにより、処理中のローディング表示や、エラー時のメッセージ表示などを簡単に実装できます。
リアルタイム更新
Live Provider(リアルタイムでデータの変更を通知する仕組み)を利用している場合、作成操作が成功するとliveProvider
のpublish
メソッドが呼ばれ、他のクライアントに変更を通知できます。複数のユーザーが同時に使用するアプリケーションで便利な機能です。
クエリの自動無効化
作成操作が成功すると、同じリソースの"list"
や"many"
クエリが自動的に無効化(再取得)され、UIが最新のデータに更新されます。例えば、商品を新規登録した後、商品一覧画面が自動的に更新されて新しい商品が表示されるといった動作が、追加のコードなしで実現できます。
追加機能
監査ログ(Audit Log Provider利用時)や、通知のカスタマイズ、メタ情報の付与なども可能です。これらの機能により、より高度なデータ管理が実現できます。
5. 基本的な使い方
それでは、実際のコードでuseCreateの使い方を見ていきましょう。
基本のコード例
import { useCreate } from "@refinedev/core";
const { mutate, mutation } = useCreate({ resource: "products" });
mutate({
values: {
name: "New Product",
material: "Wood",
},
});
// 状態の確認
console.log(mutation.isLoading); // ローディング中かどうか
console.log(mutation.data); // レスポンスデータ
console.log(mutation.error); // エラー情報
このコードでは、useCreate
を使って”products”というリソースに新しい商品データを作成しています。
パラメータの説明
useCreateとmutateメソッドでは、以下のパラメータを指定できます。
resource:作成対象のリソース名(APIエンドポイントなど)を指定します。上の例では”products”を指定しています。
values:作成するデータの内容を指定します。オブジェクト形式で、作成したいデータのフィールドと値を記述します。
meta:追加情報を渡すためのオプションです。例えば、カスタムヘッダーなどをAPIリクエストに含めたい場合に使用します。
mutationOptions:成功時や失敗時のコールバック、リトライ回数など、TanStack Queryのオプションを指定できます。
状態の確認
mutation
オブジェクトを使えば、処理の状態を簡単に確認できます。
mutation.isLoading
:データ作成処理が実行中かどうかを示しますmutation.data
:作成が成功した場合のレスポンスデータが格納されますmutation.error
:エラーが発生した場合のエラー情報が格納されます
これらの状態を使って、ローディング表示やエラーメッセージの表示などを実装できます。
6. mutateとmutateAsyncの違い
useCreateには、mutate
とmutateAsync
という2つのメソッドが用意されています。この2つの違いを理解することは、useCreateを効果的に使う上で重要です。
mutateとは
mutateは、データを作成・送信するための関数です。「データを登録してください」と命令するイメージです。
特徴
- 戻り値なし(void)
- 実行したら「後はよろしく」という感じで、結果を待たない
- Promise(約束)を返さない
基本的な書き方
const { mutate } = useCreate();
mutate({
resource: "posts",
values: {
title: "初めての投稿",
content: "こんにちは"
}
});
// mutateの結果を待たずに次の行が実行される
mutateAsyncとは
mutateAsyncも、データを作成・送信するための関数ですが、こちらは「完了するまで待つ」ことができます。
特徴
- Promiseを返す(結果を待てる)
- async/awaitと組み合わせて使う
- 成功したデータや、エラー情報を取得できる
基本的な書き方
const { mutateAsync } = useCreate();
// awaitを使って完了を待つ
const result = await mutateAsync({
resource: "posts",
values: {
title: "初めての投稿",
content: "こんにちは"
}
});
// ここは mutateAsync が完了してから実行される
console.log(result.data); // 作成されたデータを取得できる
比較表
項目 | mutate | mutateAsync |
---|---|---|
結果を待つ | ✗ 待たない | ✓ 待てる |
戻り値 | なし(void) | Promise |
async/await | 不要 | 必要 |
結果の取得 | できない | できる |
エラー処理 | onErrorオプション | try/catchで可能 |
別名の付け方
同じコンポーネント内で複数のuseCreateを使う場合、別名をつけないと名前が衝突してしまいます。以下のように別名をつけることができます。
const { mutate: createPost } = useCreate();
// mutate の代わりに createPost という名前で使える
createPost({
resource: "posts",
values: { title: "こんにちは" }
});
mutateAsyncにも同様に別名をつけられます。
const { mutateAsync: createPostAsync } = useCreate();
// mutateAsync の代わりに createPostAsync という名前で使える
await createPostAsync({
resource: "posts",
values: { title: "こんにちは" }
});
7. まとめ
この記事では、RefineのuseCreateデータフックについて、基本的な使い方から2つのメソッドの違いまでを解説しました。
useCreateを使えば、データの新規作成処理を数行のコードで実装でき、ローディング状態の管理やエラーハンドリング、クエリの自動無効化といった機能が自動的に提供されます。また、mutate
はシンプルな登録処理に、mutateAsync
は結果を待って次の処理を行いたい場合に使うという使い分けも理解できたと思います。
useCreateはRefineのデータフックの一つに過ぎません。データの更新にはuseUpdate
、削除にはuseDelete
、一覧取得にはuseList
といったフックも用意されています。これらを組み合わせることで、より完成度の高いアプリケーションを効率的に開発できるでしょう。
まずはuseCreateを実際に使ってみて、Refineの便利さを体感してみてください。