makoxti
@makoxti

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

初期表示時にapiを叩いてレスポンス値を画面に表示したい

Q&A

Closed

解決したいこと

apiから受け取ったデータを画面表示させたい

発生している問題・エラー

発生しているエラーはなし

該当するソースコード

import React, { useCallback, useEffect, useState } from "react";
import axios from "axios";

interface ResponseData {
  posts: ApiResponseData[];
}
interface ApiResponseData {
  id: number;
  name: string;
  color: string;
  age: number;
}
const Crud = () => {
  const [posts, setPosts] = useState<ResponseData | []>([]);
  useEffect(() => {
    axios
      .get("http://localhost:8000/api/hedgehogs/")
      .then((response) => {
        if (response.data) {
          setPosts(response.data);
        } else {
          console.log("responmseデータがありません");
        }
      })
      .catch(() => {
        console.log("通信に失敗しました");
      });
  }, []);

  if (!posts) {
    return null;
  }
  return (
    <>
      <p>responseデータ</p>
      {posts.map((post) => (
        <div key={post.id}>
          <p>{post.name}</p>
          <p>{post.age}</p>
        </div>
      ))}
    </>
  );
};

export default Crud;
from typing import List
from fastapi import APIRouter

router = APIRouter()

@router.get("/")
async def get_all_hedgehogs() -> List[dict]:
    hedgehogs = [
        {"id": 1, "name": "momo", "color": "SALT & PEPPER", "age": 2},
        {"id": 2, "name": "coco", "color": "DARK GREY", "age": 1.5}
    ]

    return hedgehogs

よろしくお願いします。

0

2Answer

const [posts, setPosts] = useState<ApiResponseData>([]);

としておけばとりあえずはエラーは出ないと思います。

postsは初期状態としては();なのでundefinedです。getApiData()からsetPostsが呼ばれてはじめてデータが入ります。
その初期状態時にもrenderは走るので、undefined.map(...)という事をすることになり、今回のエラー表示になっています。

なので、初期値を[]としておけばとりあえずはエラーは回避できます。

または

if(!posts){
  return null
}

return ( ...

としておけば、主となるrenderが走らないのでエラーは発生しません。

0Like

Comments

  1. @makoxti

    Questioner

    ありがとうございます。
    rendermが走らない方法は初めて知りました。

    実装方法を少し変えてみたらエラーは発生しなくなったのですが、APIから返ってきた値を画面表示できなくて原因がわかりません。
    もしわかればご教授頂きたいです。
[
  {"id": 1, "name": "momo", "color": "SALT & PEPPER", "age": 2},
  {"id": 2, "name": "coco", "color": "DARK GREY", "age": 1.5}
]

これがapiから返ってくることを期待しているのであれば、

const [posts, setPosts] = useState<ResponseData | []>([]);

は、素直に

const [posts, setPosts] = useState<ApiResponseData[]>([]);

では?

また、初期値を[]とするなら、基本的には

if (!posts) {
  return null;
}

は要らないのでは?

.then((response) => {
  if (response.data) {
    setPosts(response.data);
  } else {
    console.log("responmseデータがありません");
  }
})

で、responseをconsole.logしたら何が返ってきますか?.dataは無いような気がしますが...

0Like

Comments

  1. @makoxti

    Questioner

    以下の実装で解決しました。

    import React, { useCallback, useEffect, useState } from "react";
    import axios from "axios";

    interface ResponseData {
    posts: ApiResponseData[];
    }
    interface ApiResponseData {
    id: number;
    name: string;
    color: string;
    age: number;
    }
    const Crud = () => {
    const [posts, setPosts] = useState<ResponseData | []>([]);
    useEffect(() => {
    axios
    .get("http://localhost:8000/api/hedgehogs/")
    .then((response) => {
    if (response.data) {
    setPosts(response.data);
    } else {
    console.log("responmseデータがありません");
    }
    })
    .catch(() => {
    console.log("通信に失敗しました");
    });
    }, []);

    return (
    <>
    <p>responseデータ</p>
    {posts.map((post) => (
    <div key={post.id}>
    <p>{post.name}</p>
    <p>{post.age}</p>
    </div>
    ))}
    </>
    );
    };

    export default Crud;

Your answer might help someone💌