react-native について
データ駆動型のモバイル画面を構築する開発者向けに、JSON 仕様を React Native のネイティブコンポーネントツリーへ変換するレンダラーです。標準 UI コンポーネントに加え、状態バインディング、条件付き表示、アクションを備えています。
主な機能
- 01ネイティブのレイアウト・コンテンツコンポーネント
- 02フォーム入力とフィードバック用コンポーネント
- 03状態とリスト項目のデータバインディング
- 04条件付き表示と動的プロパティ
- 05組み込みの状態アクション
- 06外部状態ストアへの対応
活用シーン
- 01JSON 仕様からモバイル画面を描画
- 02双方向バインディングを使ったフォーム構築
- 03状態に応じた要素の表示切り替え
- 04外部状態ストアとの連携
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vercel-labs/ json-render --skill react-nativeインストール後、Claude Code で/react-nativeを入力して読み込まれたか確認します。
詳細
@json-render/react-native
JSON 仕様を、標準コンポーネント、データバインディング、表示制御、アクション、動的プロパティを備えたネイティブモバイルコンポーネントツリーに変換する React Native レンダラーです。
クイックスタート
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react-native/schema";
import {
standardComponentDefinitions,
standardActionDefinitions,
} from "@json-render/react-native/catalog";
import { defineRegistry, Renderer, type Components } from "@json-render/react-native";
import { z } from "zod";
// Create catalog with standard + custom components
const catalog = defineCatalog(schema, {
components: {
...standardComponentDefinitions,
Icon: {
props: z.object({ name: z.string(), size: z.number().nullable(), color: z.string().nullable() }),
slots: [],
description: "Icon display",
},
},
actions: standardActionDefinitions,
});
// Register only custom components (standard ones are built-in)
const { registry } = defineRegistry(catalog, {
components: {
Icon: ({ props }) => <Ionicons name={props.name} size={props.size ?? 24} />,
} as Components<typeof catalog>,
});
// Render
function App({ spec }) {
return (
<StateProvider initialState={{}}>
<VisibilityProvider>
<ActionProvider handlers={{}}>
<Renderer spec={spec} registry={registry} />
</ActionProvider>
</VisibilityProvider>
</StateProvider>
);
}
標準コンポーネント
レイアウト
Container- パディング、背景、角丸を備えたラッパーRow- 間隔と配置を指定できる水平フレックスレイアウトColumn- 間隔と配置を指定できる垂直フレックスレイアウトScrollContainer- スクロール可能な領域(垂直または水平)SafeArea- ノッチやホームインジケーター用のセーフエリアインセットPressable- 押下時にアクションを実行するタッチ可能なラッパーSpacer- 固定または可変の余白Divider- 細い区切り線
コンテンツ
Heading- 見出しテキスト(レベル 1~6)Paragraph- 本文テキストLabel- 小さなラベルテキストImage- サイズ指定モードを備えた画像表示Avatar- 円形のアバター画像Badge- 小さなステータスバッジChip- カテゴリー用のタグ/チップ
入力
Button- バリアントを備えた押下可能なボタンTextInput- テキスト入力フィールドSwitch- トグルスイッチCheckbox- ラベル付きチェックボックスSlider- 範囲スライダーSearchBar- 検索入力
フィードバック
Spinner- 読み込みインジケーターProgressBar- 進捗インジケーター
複合コンポーネント
Card- オプションのヘッダーを備えたカードコンテナListItem- タイトル、サブタイトル、アクセサリーを含むリスト行Modal- ボトムシートモーダル
表示条件
要素に visible を使用します。構文:{ "$state": "/path" }、{ "$state": "/path", "eq": value }、{ "$state": "/path", "not": true }、AND 条件には [ cond1, cond2 ] を使用します。
Pressable + setState パターン
タブバーのようなインタラクティブな UI では、組み込みの setState アクションと Pressable を使用します。
{
"type": "Pressable",
"props": {
"action": "setState",
"actionParams": { "statePath": "/activeTab", "value": "home" }
},
"children": ["home-icon", "home-label"]
}
動的プロパティ式
任意のプロパティ値を、レンダリング時に解決されるデータ駆動型の式にできます。
{ "$state": "/state/key" }- 状態モデルから読み取ります(一方向の読み取り){ "$bindState": "/path" }- 双方向バインディングです。フォームコンポーネントの自然な値プロパティ(value、checked、pressed など)に使用します。{ "$bindItem": "field" }- 繰り返し項目のフィールドに双方向バインディングします。繰り返しスコープ内で使用します。- 入れ子のリストには、外側の繰り返し内で
{ "repeat": { "statePath": { "$item": "comments" } } }を使用します。 { "$cond": <condition>, "$then": <value>, "$else": <value> }- 条件付きの値
{
"type": "TextInput",
"props": {
"value": { "$bindState": "/form/email" },
"placeholder": "Email"
}
}
コンポーネントでは、双方向バインディングに statePath プロパティを使用しません。代わりに、自然な値プロパティで { "$bindState": "/path" } を使用します。
組み込みアクション
setState アクションは ActionProvider によって自動的に処理され、状態モデルを直接更新します。その結果、表示条件と動的プロパティ式が再評価されます。
{ "action": "setState", "actionParams": { "statePath": "/activeTab", "value": "home" } }
プロバイダー
| プロバイダー | 目的 |
|---|---|
StateProvider | コンポーネント間で状態を共有します(JSON Pointer パス)。制御モード用の store プロパティを任意で指定できます。 |
ActionProvider | コンポーネントからディスパッチされたアクションを処理します |
VisibilityProvider | 状態に基づく条件付きレンダリングを有効にします |
ValidationProvider | フォームフィールドの検証を行います |
外部ストア(制御モード)
StateProvider(または JSONUIProvider / createRenderer)に StateStore を渡すと、外部の状態管理を使用できます。
import { createStateStore, type StateStore } from "@json-render/react-native";
const store = createStateStore({ count: 0 });
<StateProvider store={store}>{children}</StateProvider>
store.set("/count", 1); // React re-renders automatically
store が指定されている場合、initialState と onStateChange は無視されます。
主要なエクスポート
| エクスポート | 目的 |
|---|---|
defineRegistry | カタログから型安全なコンポーネントレジストリを作成します |
Renderer | レジストリを使用して仕様をレンダリングします |
schema | React Native の要素ツリーのスキーマ |
standardComponentDefinitions | すべての標準コンポーネントのカタログ定義 |
standardActionDefinitions | 標準アクションのカタログ定義 |
standardComponents | 事前に構築されたコンポーネント実装 |
createStandardActionHandlers | 標準アクション用のハンドラーを作成します |
useStateStore | 状態コンテキストにアクセスします |
useStateValue | 状態から単一の値を取得します |
useBoundProp | $bindState/$bindItem による双方向の状態バインディング |
useStateBinding | (非推奨) パスを使用した従来の双方向バインディング |
useActions | アクションコンテキストにアクセスします |
useAction | 単一のアクションディスパッチ関数を取得します |
useUIStream | API エンドポイントから仕様をストリーミングします |
createStateStore | フレームワークに依存しないインメモリの StateStore を作成します |
StateStore | 外部の状態管理を接続するためのインターフェース |