ちょっと話題の記事

管理画面を作るフレームワークrefineを使って、Next.jsで管理画面を作ってみた

管理画面って作るのめんどくさくないですか?そんなわけでrefineを使ってみました。 refineは、管理画面を作成するためのReactベースのフレームワークです。refineを使ってNext.jsな管理画面を作ってみました。
2023.11.22

管理画面って作るのめんどくさくないですか?

管理画面は一般的に、データのCRUD(Create, Read, Update, Delete)が行えるデータの管理画面として使われることが多いです。

そうすると、一覧画面があって、データの登録画面があって、データの編集画面があって、データの削除画面があって、データの詳細画面があって…、という感じで大体似たような画面を作ることになります。

そういった手間を軽減するために、refine を試してみました。

refine は、管理画面を作成するためのReactベースのフレームワークです。

こんな感じの管理画面を簡単に作れます。

refineの面白いところは、Next.jsVite といったアプリケーションフレームワークや、Material UIAnt Design といったUIフレームワーク、REST APIGraphQL といったデータ取得先を選択して組み合わせて使えるところです。

今回は、Next.jsとMaterial UIを使って、refineで管理画面を作ってみたので紹介します。

refineプロジェクトのセットアップ

refineは、create-refine-appというコマンドでプロジェクトを作成します。

以下のコマンドを実行することで、対話形式でプロジェクトを作成できます。

$ npm create refine-app@latest

プロジェクトのプラットフォームを、以下4つのフレームワークから選択できます。

  • Vite
  • Next.js
  • Remix
  • CRA [Legacy]

今回は Next.js を使いたいので選択します。

? Choose a project template …
  Vite Creates a refine React Vite project.
❯ Next.js Creates a refine Next.js project with SSR support.
  Remix Creates a refine Remix project with SSR support
  CRA [Legacy] Creates a basic refine project

ちなみに、2023/11/22現在、Next.jsを選択すると、Page RouterのNext.jsが作られます。App RouterのNext.jsでのプロジェクトセットアップはまだ未対応です。

App RouterのNext.jsも対応自体はしているので、サンプルを参考にすれば構築できそうです。

次にプロジェクト名の入力を求められるので、適当に入力します。

? What would you like to name your project?: › sample

データの登録や取得をするバックエンドサービスを以下の中から選択します。

  • REST API
  • NestJS Query
  • GraphQL API
  • Strapi v4
  • nestjsx-crud
  • Airtable
  • Supabase
  • Appwrite
  • Hasura
  • Medusa

今回は REST API を使いたいので選択します。

? Choose your backend service to connect: …
❯ REST API Installs REST API Data Provider.
  NestJS Query Installs NestJS Query Data Provider.
  GraphQL API Installs GraphQL API Data Provider.
  Strapi v4 Installs Strapi v4 Data Provider.
  nestjsx-crud Installs Nestjsx-crud Data Provider.
  Airtable Installs Airtable Data Provider.
  Supabase Installs Supabase Data Provider.
  Appwrite Installs Appwrite Data Provider.
  Hasura Installs Hasura Data Provider.
  Medusa Installs Medusa Data Provider.

UIフレームワークの選択を求められるので、以下の中から選択します。

  • No UI
  • Ant Design
  • Material UI
  • Mantine
  • Chakra UI

今回は Material UI を使いたいので選択します。

? Do you want to use a UI Framework?: …
  Headless No UI framework package will be installed.
  Ant Design Installs Ant Design package.
❯ Material UI Installs Material UI package.
  Mantine Installs Mantine package.
  Chakra UI Installs Chakra UI package.

サンプルページを作成するかどうかを聞かれるので、作成します。

? Do you want to add example pages?: …
  No No examples will be installed.
❯ Yes (Recommended) Installs example pages.

認証サービスを使うかどうかを聞かれるので、今回は使わないようにします。

? Do you need any Authentication logic?: …
❯ None No Auth Provider will be installed.
  Custom Installs a mock Auth Provider.
  Auth0 Installs Auth0 with NextAuth.js
  Google Installs Google with NextAuth.js
  Keycloak Installs Keycloak with NextAuth.js

i18nをサポートするかどうかを聞かれるので、今回は使わないようにします。

? Do you need i18n (Internationalization) support?: …
❯ No No i18n packages will be installed.
  Yes Installs i18n packages.

javascrpitのパッケージマネージャーを聞かれるので、今回はnpmを選択します。

? Choose a package manager: …
❯ Npm Dependencies will be installed via npm
  Yarn Dependencies will be installed via yarn

そうすると、インストールが開始されるので、しばらく待ちます。

インストール完了後に、以下コマンドを実行することでrefineの作成したサンプルの管理者画面を確認できます。

$ npm run dev

作成されたサンプルの管理画面は、こんな感じです。ブログの管理画面のような感じです。

項目ごとにソートアイコンがついていて、ソートができます。

ポストの作成、編集、詳細ページ表示、削除なんかも用意されています。

ちなみに、コマンドでサンプル画面を作った場合、データは以下のPublicなREST APIから取得するように作られています。

一覧画面をカスタマイズする

一覧画面を再掲します。

この一覧画面は、refineの Inferencer という機能で自動生成されています。

一覧画面を描画している pages/blog-posts/index.tsx を見てみると、MuiListIneferencer コンポーネントだけで一覧画面が作成されていることがわかります。

pages/blog-posts/index.tsx

import { MuiListInferencer } from "@refinedev/inferencer/mui";
import { GetServerSideProps } from "next";

export default function BlogPostList() {
  return <MuiListInferencer />;
}

export const getServerSideProps: GetServerSideProps<{}> = async (context) => {
  return {
    props: {},
  };
};

InferencerはCRUD(作成、読み取り、更新、削除)ページを素早く生成するためのコンポーネントです。 ビューのコードを自動生成できるので、典型的なCRUDページをすぐに作成してカスタマイズが可能です。

Inferencerコンポーネントで描画された画面では下のようにポップアップが出てきて、自動的に同様の画面を描画するコードを生成してくれるので、これを利用して実際の画面を作ります。

これをコピー&ペーストして、pages/blog-posts/index.tsx にそのまま貼り付けると、現状エラーが出てしまいました。

単にdefault exportができていないだけだったので、export default BlogPostList をしてあげると動きます。

実際の一覧画面のページを描画しているtsxファイルは、以下のようになっています。

これで、画面のコンポーネントを自由にカスタマイズできるようになりました。

フィルターを追加してみる

一覧画面は、Material UIのDataGridコンポーネントで作成されているので、次のドキュメントを参考にして、フィルターをテーブルの上部に追加してみます。

DataGridコンポーネントに slots={{toolbar: GridToolbar}} を指定することで、フィルターを追加できます。

        <List>
            <DataGrid
                {...dataGridProps}
                slots={{toolbar: GridToolbar}}
                columns={columns}
                autoHeight
            />
        </List>

こんな感じで絞り込みができるようになりました。

画面のコンポーネントを柔軟にカスタマイズできるので、やろうと思えば色々できそうです。

おわりに

refineを使って、管理画面を作ってみました。 アプリケーションフレームワークやUIフレームワークをいくつか選択できるので、自分の好きなフレームワークを選んで作れるのは良いですね。 数分で動かせるサンプルの管理画面が作れるのには感動します。

今回はさわり程度で数ある機能をまだまだ使いこなせていませんが、今後も使ってみたいと思います。

サンプルプログラム置き場