概要
SpringBootで作ったRestApiをフロントエンド側で使います。
標準搭載されているfetchは使わないでaxiosを使っております。
開発環境
開発環境
OS:windows10
バックエンド側:
IDE:IntelliJ Community
spring-boot-starter-parent 2.75
java : 11
フロントエンド:
IDE:VScode
├── @types/node@18.11.15
├── @types/react-dom@18.0.9
├── @types/react@18.0.26
├── axios@1.2.1
├── eslint-config-next@13.0.6
├── eslint@8.29.0
├── next-auth@4.18.7
├── next@13.0.6
├── react-bootstrap@2.7.0
├── react-dom@18.2.0
├── react@18.2.0
├── styled-components@5.3.6
├── styled-jsx@5.1.1
└── typescript@4.9.4
構成
全体の構成としては以下の構成になっております。
実装
バックエンド(SpringBoot)側
実装できているものとして Postmanで確認します。
Postmanで検証
E2EテストでSpringBootのRestApiがしっかり動作しているか確認します。
[
{
"id": 0,
"name": "生鮮食品",
"alias": "Food",
"parent": null,
"children": [
1,
2,
3,
5,
11
]
},
{
"id": 1,
"name": "食肉",
"alias": "Meat",
"parent": 0,
"children": []
},
{
"id": 2,
"name": "魚",
"alias": "Fish",
"parent": 0,
"children": []
},
{
"id": 3,
"name": "野菜",
"alias": "Vegetable",
"parent": 0,
"children": []
},
{
"id": 4,
"name": "卵、乳製品",
"alias": "DairyProduct",
"parent": null,
"children": [
12,
13
]
},
{
"id": 5,
"name": "缶詰",
"alias": "Cannning",
"parent": 0,
"children": []
},
{
"id": 6,
"name": "日用品",
"alias": "Commodity",
"parent": null,
"children": [
7,
8,
9,
10
]
},
{
"id": 7,
"name": "キッチン消耗品",
"alias": "aaaaa",
"parent": 6,
"children": []
},
{
"id": 8,
"name": "洗濯用品",
"alias": "wq",
"parent": 6,
"children": []
},
{
"id": 9,
"name": "文房具",
"alias": "wqqq",
"parent": 6,
"children": []
},
{
"id": 10,
"name": "家電",
"alias": "dfafda",
"parent": 6,
"children": []
},
{
"id": 11,
"name": "果物",
"alias": "Fruit",
"parent": 0,
"children": []
},
{
"id": 12,
"name": "卵",
"alias": "Egg",
"parent": 4,
"children": []
},
{
"id": 13,
"name": "牛乳",
"alias": "Milk",
"parent": 4,
"children": []
}
]
フロントエンド側
ソースコード
/**
* @remarks 商品のカテゴリーを表す型です。
*
* @auther RYA234
*
*/
export type Category = {
/** MySQL側のIDです。*/
id:number
/** リンクとしてつかうので英語が入ります。 */
alias:string
/** html上で表示されるカテゴリー名称です。日本語が入ることを想定してます。 */
name:string
/** サブカテゴリーです。サブカテゴリーを持つ場合対応するidが入ります。サブカテゴリーがない場合はnullが入ります。 */
children:number[]
}
import axios from 'axios';
export const getCategories = () =>{
return axios.get(`http://127.0.0.1:5000/api/category/all`);
};
import { Category } from "../../types/category";
import * as categoryService from "../../service/categoryService";
import { useEffect, useRef, useState } from "react";
export default function AxiosApi() {
const [categories, setCategories] = useState<Category[]>([])
// 初回実行時のみApiを読み込む
useEffect(() => {
loadCategories();
}, [])
const loadCategories = async () => {
categoryService
.getCategories()
.then((response) => {
setCategories(response.data)
console.log(response.data)
});
}
return (
<div>
<h1>axiosを使ったデータ取得</h1>
カテゴリー名 、サブカテゴリーのid
{
categories.map((category: Category) => {
return (
<div key={category.id}>
{category.name}、 {category.children}
</div>
)
})
}
</div>
)
}
詰まった点
useEffectを使っていない場合 useStateを使った場合 serviceが連打されるので注意
以下gifアニメはapiが連打されそれに伴いconsole.log(response.data)が実行されている様子です。
参考
UseEffect説明
わかりやすかった!