• トップ
  • ブログ一覧
  • React-Adminを使ってみた
  • React-Adminを使ってみた

    おか(エンジニア)おか(エンジニア)
    2024.05.14

    IT技術

    React-Adminを使う機会があったので少しまとめてみました!

    📌 React-Adminとは

    React-Adminとは、B2Bアプリ向けのReactフレームワークです。
    公式サイトによると、2万5千以上の企業に使われているそうです(2024年5月確認)。

    📌 特徴

    SPA

    React-AdminはSPAです。
    その結果、ページ遷移が速く、ホスティングが簡単で、APIとの接続も簡潔になります。

    また、Next.jsやRemix内での使用可能ですし、もちろんReact + Vite環境でも使うことができます。

    React界隈の主要なライブラリが使われている

    Material UI, React Router, React Hook Form, React Query(TanStack Query) などが内部で使われています。

    挙動をカスタマイズするときは、これらのライブラリのオプションをそのまま指定することもあるため、慣れている人にとっては使いやすいかもしれません。

    様々な機能を簡単に作れる

    いくつかセットアップは必要ですが、それ以降はReact-Adminが提供するコンポーネントを組み合わせると様々な機能が簡単に作れます。

    例えば、作成、編集などのフォーム、詳細・一覧表示(検索、並び替え、CSV出力等を含む)などのCRUD機能を持つページや、テーマ切り替え、レスポンシブ、i18n、認可制御などの機能へも対応しています。

    有料のエンタープライズプランにすると、より高度な機能やコンポーネントを使うことができます。

    📌 長所・短所

    感じた長所、短所です。

    長所

    • 機能実装がすぐできる
    • 提供されているコンポーネントでほぼ全ての機能が実現できる

    短所

    • 多機能なので仕様把握が大変
    • 提供外のインターフェースや仕様を実装しようとすると、難易度が上がる
    • 一部の機能は有料のエンタープライズプランでのみ提供

    📌 基本的な作り方の流れ

    絶対これ!という流れではないですが、使うイメージを上げるために、大まかな流れを説明します。

    1. リソースごとのCRUD APIを用意する

    React-Adminがリソース情報を取得するAPIを用意します。
    できるだけ、リソース共通で統一したインターフェースにしたほうが、Data Providerの設定はやりやすいかもしれません。

    2. APIに合わせて、Data Providerを設定する

    Data Providerとは、APIのデータフェッチに使われるプロバイダーです。
    Data Providerの中身はオブジェクトで、フェッチの種類別(リスト取得、1件取得、作成、更新等)にパラメーターやエンドポイントを定義します。以下はdataProviderの抜粋例です。

    1// ...
    2const dataProvider = {
    3  // 特定のリソースをリストで取得する。ページネーション、絞り込み、ソートのパラメーターあり
    4  getList: async (resource, params) => {
    5    const query = {
    6      ...getFilterQuery(params.filter),
    7      ...getPaginationQuery(params.pagination),
    8      ...getOrderingQuery(params.sort),
    9    };
    10    const url = `${apiUrl}/${resource}/?${stringify(query)}`;
    11
    12    const { json } = await httpClient(url);
    13
    14    return {
    15      data: json.results,
    16      total: json.count,
    17    };
    18  },
    19  // 特定のリソースのアイテムを1つid指定で取得する
    20  getOne: async (resource, params) => {
    21    const data = await httpClient(`${apiUrl}/${resource}/${params.id}/`)
    22      .then((response: Response) => response.json
    23    );
    24    return {
    25      data,
    26    };
    27  },
    28  // ...
    29}

    3. リソース別に任意のCRUDページを作成

    React-Admin提供のResourceコンポーネントを使って、リソース定義・そのリソースの必要ページを作成可能です。
    このResourceコンポーネントのnameは、APIのデータフェッチにも利用されます。

    1import { Admin, Resource } from 'react-admin';
    2import { ProductList, ProductCreate, ProductEdit, ProductShow } from './products';
    3import { StoreList } from './stores';
    4import { dataProvider } from './dataProvider'
    5
    6const App = () => (
    7  {/* AdminはReact-Adminのルートコンポーネント */}
    8  <Admin dataProvider={dataProvider}>
    9    {/* ProductのCRUDページ */}
    10    <Resource name="product" list={ProductList} create={ProductCreate} edit={ProductEdit} show={ProductShow} />
    11    {/* Storeはリストページのみ */}
    12    <Resource name="stores" list={StoreList} />
    13  </Admin>
    14);

    以下は、Productリソースのlistページに使用されるコンポーネントです。見て分かるように、React-Adminのコンポーネントを組み合わせて、必要なpropsを指定するだけで十分な機能を実装できます。

    1import {
    2  List,
    3  TextField,
    4  TextInput,
    5  ReferenceField,
    6  ReferenceInput,
    7  DatagridConfigurable,
    8  TopToolbar,
    9  SelectColumnsButton,
    10  FilterButton,
    11  CreateButton,
    12  ExportButton,
    13} from 'react-admin'
    14
    15// 🔍 リストの絞り込み設定
    16const filters = [
    17  // productとstoreは、多対1の関係であり、productはstore_idの外部キーを持ちます
    18  // ReferenceInputでは、store_idに基づいたproductの絞り込みを可能にします
    19  <ReferenceInput
    20    key="store_id"
    21    source="store_id"
    22    reference="stores"
    23    alwaysOn
    24    resettable
    25  />,
    26  // sourceはAPIによって変わります
    27  <TextInput
    28    key="product_name"
    29    source="name__icontains"
    30    alwaysOn
    31    resettable
    32  />
    33]
    34
    35// 🧰 リストのツール
    36// 表示カラムの編集や、CSV出力など
    37const ListActions = () => (
    38  <TopToolbar>
    39    <SelectColumnsButton />
    40    <FilterButton />
    41    <CreateButton />
    42    <ExportButton />
    43  </TopToolbar>
    44)
    45
    46export const ProductList = () => {
    47  return (
    48    <List
    49      actions={<ListActions />}
    50      filters={filters}
    51      pagination={<Pagination rowsPerPageOptions={[10, 20]} />}
    52    >
    53      <DatagridConfigurable rowClick={editIfNoTextSelected}>
    54        {/* 📝 リストの表示項目 */}
    55        <TextField source="id" />
    56        <TextField source="name" />
    57        <ReferenceField
    58          source="store_id"
    59          reference="stores"
    60        />
    61      </DatagridConfigurable>
    62    </List>
    63  )
    64}

    リストページの表示はこんな感じになります。上部のStore, Nameは絞り込みに使うインプットです。一覧は、カラム基準の並び替えもできます。

    リレーション先のデータ取得も簡単

    追加APIを用意することなく、各リソースのCRUDのAPIだけでリレーション先のデータ取得も正しく行なってくれます。

    例えば、一覧に表示されている各Productのリレーション先のStore取得・表示もその1つです。コンポーネントで言うと以下の箇所です。

    1<ReferenceField source="store_id" reference="stores" />

    React-Adminは、Product情報を取得した後に、StoreのAPIに向けて、以下のようなクエリを発行しています。

    1GET https://api.example.com/stores?filter={ids:[1,2,3,4,5,6,7]}

    idを1つずつコールするのではなくまとめて行うことで、N+1問題を回避する仕組みになっていることがわかります。

    セレクトのインクリメント検索も対応済み

    上記のコード内のReferenceInputはデフォルトでインクリメント検索に対応しており、文字列を入力すると、部分一致するオプションを絞り込んでくれます。

    こういう機能がデフォルトで動くのはすごく有難いですね。

    📌 向いているプロジェクト

    実際に触ってみた感覚では、以下のようなプロジェクトに向いているかと思いました👀

    • 小〜中規模
    • 開発スピードが重要
    • SEOが重要ではなく、UIのこだわりも少ないアプリケーション
    • ほとんどの機能がReact-Admin提供のもので事足りる

    📌 まとめ

    React-Adminは使用ケースを選ぶフレームワークだと思いますが、ハマると開発スピードがぐっと速くなると思います。皆さんも機会があれば検討してみてくださいー!

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background