自分自身のメモも兼ねて。
自作した競馬データベースapiから、Reactのコンポーネントによって情報を取得
DetailRace.jsx
import { useState,useEffect,useRef,React} from "react";
import { Link } from "react-router-dom";
import { useParams } from "react-router-dom";
import axios from "axios";
export const DetailRace=()=>{
const {raceid}=useParams();
const RefError=useRef(null)
const RefEffectCounter=useRef(0)
const [data,setData]=useState(null)
const RefMainData=useRef([])
const RefJockeyData=useRef(null)
const RefRaceData=useRef(null)
const RefHorseData=useRef(null)
const RefLoading=useRef(true)
RefEffectCounter.current=0
const GetData=async(id)=>{
try{
const res=await axios.get('http://localhost:8000/api/race_detail/'+String(id))
setData(res.data)
}catch(error){
RefError.current=error
}
finally{
RefLoading.current=false
}
}
useEffect(()=>{
RefEffectCounter.current+=1
if(RefEffectCounter.current==1){
GetData(raceid)
}
},[raceid])
class CreateDataObj{
constructor(obj){
this.obj=obj;
this.horse_obj=obj.horse;
this.jockey_obj=obj.jockey;
this.race_obj=obj.race;
}
MainKeySet(){
this.obj['馬名']=this.obj.horse.馬名
this.obj['騎手名']=this.obj.jockey.騎手名
const keySet=['着順','馬番','枠番','馬名','騎手名','オッズ','タイム','単人気','着差','斥量','体重','体重変化','性齢']
let dict={}
keySet.forEach((key)=>{
dict[key]=this.obj[key]
})
return dict
}
}
const CreateMainData=(objs)=>{
let MainArry=Array(0)
objs.forEach((obj)=>{
const inst=new CreateDataObj(obj)
MainArry.push(inst.MainKeySet())
})
RefMainData.current=MainArry
}
const CreateOtherData=(objs)=>{
const inst=new CreateDataObj(objs[0])
RefRaceData.current=inst.race_obj
RefHorseData.current=inst.horse_obj
RefJockeyData.current=inst.jockey_obj
}
if(data){
CreateMainData(data)
CreateOtherData(data)
}
if (RefError.current){
return <div>
<p>エラーが起きました。</p>
<p>{String(RefError.current)}</p>
</div>
}
else if(RefLoading.current){
return(
<div>
<h2>Loading...</h2>
</div>
)
}
else{
return(
<div>
<table>
<tbody>
<tr>
{Object.keys(RefMainData.current[1]).map((key,i)=>(
<td key={i}>{key}</td>
))}
</tr>
{RefMainData.current.map((obj,i)=>(
<tr key={i}>
{
Object.keys(obj).map((key,j)=>(
<td key={j}>{obj[key]}</td>
))
}
</tr>
))}
</tbody>
</table>
<Link to={`/detail_race/202201010101`}>こちら</Link>
</div>
)
}
}
DetailRace.jsx
<Link to={`/detail_race/202201010103`}>こちら</Link>
で、試験的に別レースの再描画を試みている。
このコードでは、
raceidが更新-->第二引数が[raceid]のuseEffectが発火-->useEffect内でdataが更新
-->再レンダリング-->再描画
の順で実行されることで、aタグではなく、Link to= を使った再描画を実現できた。
ちなみに、apiから渡されるデータは以下のようなもの。
[
{
"id": 45756,
"horse": {
"id": 238,
"馬名": "アンテロース",
"horse_id": "2020100678"
},
"jockey": {
"id": 25,
"騎手名": "武豊",
"jockey_id": "00666"
},
"race": {
"id": 3316,
"天気": {
"id": 1,
"天気": " 曇 "
},
"状態": {
"id": 3,
"状態": " 稍重 "
},
"開催地": {
"id": 1,
"開催地": "札幌",
"開催番号": "01"
},
"レース名": "2歳未勝利",
"race_id": "202201010101",
"距離": "右1800m ",
"日付": "2022-07-23T09:50:00Z",
"単": "120",
"複": "100,210",
"枠": null,
"馬連": "520",
"ワイド": "140,110,190",
"馬単": "640",
"三連複": "200",
"三連単": "980"
},
"着順": "1",
"枠番": "1",
"馬番": "1",
"性齢": "牡2",
"斥量": "54",
"タイム": "1:53.5",
"着差": "nan",
"通過順位": null,
"上り": null,
"オッズ": "1.2",
"単人気": "1",
"体重": "436",
"体重変化": "0"
},
.
.
.
]
ただ、無駄なデータのやり取りや、RefEffectCounter
を使った場当たり的なコードなど、
改善点も多いので、今後の学習に活かしたい。