作成物
ソース(index.tsx除く)
JSON
ingredients.json
{
"title": "食材",
"testData": [
{
"name": "豚バラ",
"kinds": "肉"
},
{
"name": "キャベツ",
"kinds": "野菜"
},
{
"name": "鶏むね",
"kinds": "肉"
},
{
"name": "牛カルビ",
"kinds": "肉"
},
{
"name": "ほうれん草",
"kinds": "野菜"
},
{
"name": "にんじん",
"kinds": "野菜"
}
]
}
tsx
App.tsx
import React from 'react';
import Data from './ingredients.json'
import {makeListDivFromJson} from './makeListDivFromJson'
export const App = () => {
return (
<div>
<h1>{Data.title}</h1>
<div>{makeListDivFromJson(Data)}</div>
</div>
);
}
makeListDivFromJson.tsx
type JsonData = { testData: { name: string, kinds: string }[] };
interface HtmlList { lh: string; li: string[]; };
export const makeHtmlList = (plh: string, pli: string[]): HtmlList => {
let list: HtmlList = { lh: plh, li: pli }
return list;
}
export const makeListDivFromJson = (Data: JsonData): object[] => {
let outDiv = [];
let uniKinds = Array.from(new Set(Data.testData.map((x) => x.kinds)));
let outDivData: HtmlList[] = [];
for (let i = 0; i < uniKinds.length; i++) {//データ作成
let matchItem = Data.testData.filter(x => (x.kinds === uniKinds[i])).map(x => x.name);
outDivData.push(makeHtmlList(uniKinds[i], matchItem));
}
for (const element of outDivData) {//HTML作成
let listData = [];
outDiv.push(<h2>{element.lh}</h2>);
listData.push(element.li.map(x => <li>{x}</li>));
outDiv.push(<ul>{listData}</ul>);
}
return outDiv;
}
解説
importでJSONのデータを読み込み、処理を行う関数に渡す。
Array.fromとSetを使い、重複していない種類の配列を作る。
次にfilterで種類と一致している名前を取り出す。
最後にリストとしてdivに追加する。
詰まったところ
<ul>で囲まれていない<li>要素を連結して最終的に出力divに追加するところ。
解決方法として<li>要素を一時的に配列に保持しておき、追加し終えた際に<ul>で囲んで出力divに追加するようにした。