テーマの整理:「UI 用整形」とは何か
「UI 用整形」は、配列データを「画面コンポーネントが扱いやすい形」に変換するユーティリティのことです。 API や DB から取ってきた“生データ”は、そのままだと UI で使いづらいことが多いです。
例えばこういう悩みが出てきます。
- テーブル表示用に「列ごとの値」「表示ラベル」「フォーマット済み文字列」が欲しい
- セレクトボックス用に「value と label」のペアが欲しい
- チェックボックスリスト用に「id・表示名・選択状態」が欲しい
UI 用整形ユーティリティは、 「画面側が欲しがる形」を決めて、そこに合わせて配列を変換する」ための道具です。
基本コンセプト:「生データ → UI コンポーネント用データ」に変換する
よくある“生データ”の例
例えば、こんなユーザー配列があるとします。
const users = [
{ id: 1, name: "Alice", role: "admin", active: true },
{ id: 2, name: "Bob", role: "user", active: false },
];
JavaScriptこのままでも使えますが、UI では次のような形が欲しくなります。
- テーブル用:列ごとに「表示ラベル」「フォーマット済み値」が欲しい
- セレクトボックス用:
{ value: id, label: name }の配列が欲しい - バッジ表示用:role を「管理者」「一般ユーザー」に変換したい
こういう「UI の都合」をコードにしたものが、UI 用整形ユーティリティです。
ユーティリティ 1:セレクトボックス用 { value, label } 配列に変換する
シナリオ
ユーザー一覧から、「ユーザー選択用のセレクトボックス」を作りたい。 欲しい形はこうです。
[
{ value: 1, label: "Alice" },
{ value: 2, label: "Bob" },
]
JavaScript実装:toOptions
function toOptions(records, valueField, labelField) {
if (!Array.isArray(records) || records.length === 0) {
return [];
}
return records.map((r) => ({
value: r[valueField],
label: String(r[labelField]),
}));
}
JavaScript重要ポイントの深掘り
UI コンポーネントが期待する形を固定する 多くの UI ライブラリ(React Select など)は、 { value, label } という形を前提にしています。 ここでその形に揃えておくと、画面側のコードがシンプルになります。
label は必ず文字列にしておく String(r[labelField]) として、 数値や真偽値でも必ず文字列に変換しています。 UI は基本「文字列」を描画するので、ここで揃えておくと安心です。
例題 1:ユーザー配列をセレクトボックス用に整形する
const users = [
{ id: 1, name: "Alice", role: "admin", active: true },
{ id: 2, name: "Bob", role: "user", active: false },
];
const userOptions = toOptions(users, "id", "name");
console.log(userOptions);
JavaScript出力イメージはこうなります。
[
{ value: 1, label: "Alice" },
{ value: 2, label: "Bob" },
]
JavaScriptこの形をそのまま <select> や UI ライブラリに渡せば、 「ユーザー選択 UI」がすぐ作れます。
ユーティリティ 2:テーブル表示用に「列定義+行データ」を整形する
シナリオ
ユーザー一覧をテーブルで表示したい。 UI コンポーネントが次のような形を期待しているとします。
const columns = [
{ key: "name", header: "名前" },
{ key: "role", header: "権限" },
{ key: "state", header: "状態" },
];
const rows = [
{ name: "Alice", role: "管理者", state: "有効" },
{ name: "Bob", role: "一般", state: "無効" },
];
JavaScript表示用変換ルールを定義する
まず、「内部データ → 表示用文字列」の変換ルールを決めます。
const userDisplayMap = {
role: (v) => (v === "admin" ? "管理者" : "一般"),
active: (v) => (v ? "有効" : "無効"),
};
JavaScript実装:toTableData
function toTableData(records) {
if (!Array.isArray(records) || records.length === 0) {
return { columns: [], rows: [] };
}
const columns = [
{ key: "name", header: "名前" },
{ key: "role", header: "権限" },
{ key: "state", header: "状態" },
];
const rows = records.map((r) => ({
name: r.name,
role: userDisplayMap.role(r.role),
state: userDisplayMap.active(r.active),
}));
return { columns, rows };
}
JavaScript重要ポイントの深掘り
「内部の値」と「表示用の値」を分ける role は内部では "admin" | "user" ですが、 表示では「管理者」「一般」に変えています。 active は true/false を「有効」「無効」に変えています。
この「表示用変換」を UI 用整形の中でやっておくと、 画面側は「rows をそのまま描画するだけ」で済みます。
列定義を一箇所にまとめる columns をここで定義しておくことで、 「どの列を表示するか」「ヘッダ名は何か」が一目で分かります。 列追加・削除もこの関数だけ直せばよくなります。
例題 2:ユーザー配列をテーブル用に整形する
const users = [
{ id: 1, name: "Alice", role: "admin", active: true },
{ id: 2, name: "Bob", role: "user", active: false },
];
const table = toTableData(users);
console.log(JSON.stringify(table, null, 2));
JavaScript出力イメージはこうなります。
{
"columns": [
{ "key": "name", "header": "名前" },
{ "key": "role", "header": "権限" },
{ "key": "state", "header": "状態" }
],
"rows": [
{ "name": "Alice", "role": "管理者", "state": "有効" },
{ "name": "Bob", "role": "一般", "state": "無効" }
]
}
JavaScriptこの形をそのままテーブルコンポーネントに渡せば、 「日本語ラベル付きのきれいな一覧」が描画できます。
ユーティリティ 3:チェックボックスリスト用に「選択状態付き配列」を作る
シナリオ
ユーザー一覧から「権限付与対象ユーザー」を選ぶチェックボックスリストを作りたい。 欲しい形はこうです。
[
{ id: 1, label: "Alice", checked: false },
{ id: 2, label: "Bob", checked: true },
]
JavaScript実装:toCheckboxItems
function toCheckboxItems(records, idField, labelField, selectedIds = []) {
if (!Array.isArray(records) || records.length === 0) {
return [];
}
const selectedSet = new Set(selectedIds);
return records.map((r) => ({
id: r[idField],
label: String(r[labelField]),
checked: selectedSet.has(r[idField]),
}));
}
JavaScript重要ポイントの深掘り
選択状態を「配列 → Set」で高速に判定する selectedIds を Set に変換しておくことで、 selectedSet.has(...) で高速にチェックできます。 件数が増えてもパフォーマンスが落ちにくくなります。
UI 側は「checked をトグルするだけ」にする この形にしておくと、 画面側は「checked を true/false 切り替える」だけで状態管理ができます。 内部の id や name を意識する必要が減ります。
例題 3:ユーザー配列をチェックボックス用に整形する
const users = [
{ id: 1, name: "Alice", role: "admin", active: true },
{ id: 2, name: "Bob", role: "user", active: false },
];
const selectedIds = [2];
const items = toCheckboxItems(users, "id", "name", selectedIds);
console.log(items);
JavaScript出力イメージはこうなります。
[
{ id: 1, label: "Alice", checked: false },
{ id: 2, label: "Bob", checked: true },
]
JavaScriptこの形をそのままチェックボックスリストに渡せば、 「Bob にだけチェックが入った状態」で表示できます。
ユーティリティ 4:UI 用整形を「画面ごと」にまとめる
シナリオ
ユーザー画面、売上画面、商品画面など、 画面ごとに UI 用整形が増えていく。
整形関数をまとめたモジュールのイメージ
例えば、こんな感じでまとめておくと分かりやすいです。
export const UiShape = {
users: {
options: (users) => toOptions(users, "id", "name"),
table: (users) => toTableData(users),
checkboxes: (users, selectedIds) =>
toCheckboxItems(users, "id", "name", selectedIds),
},
// sales: { ... },
// products: { ... },
};
JavaScript使う側はこう書くだけになります。
const options = UiShape.users.options(users);
const table = UiShape.users.table(users);
const checkList = UiShape.users.checkboxes(users, [2]);
JavaScriptここでのポイントは、
- 「UI 用の形を作る処理」を一箇所に閉じ込めている
- 画面側のコードは「どの整形を使うか」だけを意識すればよい
という状態を作っていることです。
UI 用整形ユーティリティで意識してほしい重要ポイント
「UI コンポーネントの都合」をちゃんとコードにする
UI 用整形の本質は、 「コンポーネントが欲しがる形」をちゃんと決めて、それに合わせて配列を変換する」ことです。
- セレクトボックスなら
{ value, label } - テーブルなら
{ columns, rows } - チェックボックスなら
{ id, label, checked }
この“インターフェース”を決めておくと、 画面側のコードが驚くほどシンプルになります。
「生データを直接 UI に渡さない」癖をつける
生データには、
- フィールド名が UI に向いていない
- 値がそのままだと分かりづらい(コード値など)
- 表示用のフォーマットが必要(日付・金額など)
といった問題が必ずあります。
UI 用整形ユーティリティを必ず通すことで、
- フィールド名を UI 向けに揃える
- コード値をラベルに変換する
- 表示用フォーマットを適用する
という前処理を自動化できます。
手を動かして「UI 用整形」の感覚をつかむ
次のコードを実行して、
- セレクトボックス用
- テーブル用
- チェックボックス用
の 3 パターンの整形を体感してみてください。
function toOptions(records, valueField, labelField) {
if (!Array.isArray(records) || records.length === 0) {
return [];
}
return records.map((r) => ({
value: r[valueField],
label: String(r[labelField]),
}));
}
const userDisplayMap = {
role: (v) => (v === "admin" ? "管理者" : "一般"),
active: (v) => (v ? "有効" : "無効"),
};
function toTableData(records) {
if (!Array.isArray(records) || records.length === 0) {
return { columns: [], rows: [] };
}
const columns = [
{ key: "name", header: "名前" },
{ key: "role", header: "権限" },
{ key: "state", header: "状態" },
];
const rows = records.map((r) => ({
name: r.name,
role: userDisplayMap.role(r.role),
state: userDisplayMap.active(r.active),
}));
return { columns, rows };
}
function toCheckboxItems(records, idField, labelField, selectedIds = []) {
if (!Array.isArray(records) || records.length === 0) {
return [];
}
const selectedSet = new Set(selectedIds);
return records.map((r) => ({
id: r[idField],
label: String(r[labelField]),
checked: selectedSet.has(r[idField]),
}));
}
function demo() {
const users = [
{ id: 1, name: "Alice", role: "admin", active: true },
{ id: 2, name: "Bob", role: "user", active: false },
];
console.log("=== options ===");
console.log(toOptions(users, "id", "name"));
console.log("=== table ===");
console.log(JSON.stringify(toTableData(users), null, 2));
console.log("=== checkboxes ===");
console.log(toCheckboxItems(users, "id", "name", [2]));
}
demo();
JavaScriptまとめ:UI 用整形ユーティリティで「配列を、画面がそのまま使える形にする」
UI 用整形は、 「生の配列データを、UI コンポーネントがそのまま使える形に変えるためのユーティリティ」です。
プロジェクトでは、例えばこうまとめておくと扱いやすいです。
export const UiShape = {
users: {
options: (users) => toOptions(users, "id", "name"),
table: (users) => toTableData(users),
checkboxes: (users, selectedIds) =>
toCheckboxItems(users, "id", "name", selectedIds),
},
};
JavaScriptそして、
- 画面に渡す直前
- コンポーネントに props を渡す直前
など、「UI に出す入口」で必ずこの整形を通す。
そうすると、 画面側は「どの整形を使うか」だけを考えればよくなり、 配列の中身や生データの都合に振り回されなくなります。
UI は“見せ方”、整形は“見せるための準備”。 その準備を自動化してくれるのが、UI 用整形ユーティリティです。
