LoginSignup
0
0

自作した競馬データベースapiから、Reactのコンポーネントによって情報を取得

Posted at

自分自身のメモも兼ねて。
自作した競馬データベース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を使った場当たり的なコードなど、
改善点も多いので、今後の学習に活かしたい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0