无法获取 api - "Unhandled promise rejection"

Cannot fetch api - "Unhandled promise rejection"

我有一个问题,有人可以告诉我,我说得对不对,但是 React native api fetch 是随机工作的吗? 有人也可以告诉我我需要阅读什么来理解它是如何工作的,因为我想制作“pokedex”但我无法获取 api,我有这样的想法

    const getDataFromApi = async () => {
    let cancel;
    const res = await axios.get("https://pokeapi.co/api/v2/pokemon", {
      cancelToken: new axios.CancelToken((c) => (cancel = c)),
    });
    const data = await res.data.results.map((m) => m);

    setPokemon(data);

    return () => cancel();
  };
    useEffect(() => {
        getDataFromApi();
      }, [currentPageUrl]);

然后我传递参数

<ScrollView>
    <View style={styles.containerOfTiles}>
      {pokemon.map((item) => (
        <Pokecard style={styles.tileContainer}>{item}</Pokecard>
      ))}
      {/* <Pokelist pokemon={pokemon} /> */}
    </View>
  </ScrollView>

而在 Pokecard 中,我正在为每张卡片获取 pokemon,看起来像那样

    const getPokemonData = async () => {
    const res = await axios.get(url);

    const pokemonObject = await JSON.stringify(res.data);
    setPokemonData(pokemonObject);
    console.log(pokemonData.height);
  };
  useEffect(() => {
    getPokemonData();
  }, []);

在控制台中,显示未定义(只有一次显示正常高度)

我的问题: 如果我想使用来自 pokemonData 的参数,例如 type of pokemon 如果我第一次跳入此屏幕则它不起作用但是当我进入并保存任何更改时这会起作用,以其他方式是问题未定义参数。

第二个问题,每次在这个屏幕上第一次显示“未处理的承诺拒绝”但是当我删除时 console.log 然后它没有显示任何警告

抱歉,如果我写的不清楚,请解释,我会尽力纠正我的问题

(我想我做错了)提前谢谢你

//编辑 扑克牌功能组件

export default function Pokecard(props) {
  const url = props.children.url;
  const pokemonIndex = url.split("/")[url.split("/").length - 2];
  const imageUrl = `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/home/${pokemonIndex}.png`;

 
  const colorsTiles = [
    {
      rock: "rgb(148, 81, 81)",
      ghost: "rgb(247, 247, 247)",
      electric: "rgb(255, 255, 161)",
      bug: "#F6D6A7",
      poison: "#e0a7f6",
      normal: "#F4F4F4",
      fairy: "rgba(255, 192, 203, 0.863)",
      fire: "#FBE3DF",
      grass: "#E2F9E1",
      water: "#E0F1FD",
    },
  ];
  const [pokemonData, setPokemonData] = useState([]);

  const getPokemonData = async () => {
    const res = await axios.get(url).then(() => {});

    const pokemonObject = await JSON.stringify(res.data);
    setPokemonData(pokemonObject);
    console.log(pokemonData.height);
  };
  useEffect(() => {
    getPokemonData();
  }, []);
  return (
    <View
      key={props.children.name}
      style={[styles.tileContainer, { backgroundColor: "white" }]}
    >
      <Text style={styles.pokemonName}>{props.children.name}</Text>
      <View style={styles.imageBG}>
        <Image
          style={styles.pokemonImage}
          source={{
            uri: imageUrl,
          }}
        />
      </View>
    </View>
  );
}

AND 第二部分(本图鉴的主要部分)

export default function Pokedex({ navigation }) {
  const [pokemon, setPokemon] = useState([]);
  const [currentPageUrl, setCurrentPageUrl] = useState(
    "https://pokeapi.co/api/v2/pokemon"
  );
  const [nextPageUrl, setNextPageUrl] = useState();
  const [prevPageUrl, setPrevPageUrl] = useState();

  const getDataFromApi = async () => {
    let cancel;
    const res = await axios.get("https://pokeapi.co/api/v2/pokemon", {
      cancelToken: new axios.CancelToken((c) => (cancel = c)),
    });
    const data = await res.data.results.map((m) => m);

    setPokemon(data);

    return () => cancel();
  };

  useEffect(() => {
    getDataFromApi();
  }, [currentPageUrl]);
  return (
    <View
      style={[globalStyles.container, { backgroundColor: "rgb(43,41,44)" }]}
    >
      <BackButton navigation={navigation} />

      <ScrollView>
        <View style={styles.containerOfTiles}>
          {pokemon &&
            pokemon.map((item) => (
              <Pokecard style={styles.tileContainer}>{item}</Pokecard>
            ))}
          {/* <Pokelist pokemon={pokemon} /> */}
        </View>
      </ScrollView>
    </View>
  );
}

//编辑2 当我变成这样的时候

const getPokemonData = async () => {
    const res = await axios.get(url);

    const pokemonObject = await res.data;
    console.log(pokemonObject.types[0].type.name);
    setPokemonData(pokemonObject);
  };
  useEffect(() => {
    getPokemonData();
  }, []);
  return (
    <View
      key={props.children.name}
      style={[
        styles.tileContainer,
        { backgroundColor: colorsTiles[0][pokemonData.types[0].type.name] },
      ]}
    >
      <Text style={styles.pokemonName}>{props.children.name}</Text>
      <View style={styles.imageBG}>
        <Image
          style={styles.pokemonImage}
          source={{
            uri: imageUrl,
          }}
        />
      </View>
    </View>
  );

然后我得到错误“未定义不是一个对象(评估 pokemonData.Types[0])”

测试您的代码并进行一些编辑后,结果是

Pokecard.js

import axios from "axios";
import React, { useEffect, useState } from "react";
import { Image, Text, View } from "react-native";

const colorsTiles = {
    rock: "rgb(148, 81, 81)",
    ghost: "rgb(247, 247, 247)",
    electric: "rgb(255, 255, 161)",
    bug: "#F6D6A7",
    poison: "#e0a7f6",
    normal: "#F4F4F4",
    fairy: "rgba(255, 192, 203, 0.863)",
    fire: "#FBE3DF",
    grass: "#E2F9E1",
    water: "#E0F1FD",
};

const typeToColor = (pokemonType) => {
    return colorsTiles[pokemonType] ?? "white";
};

export default function Pokecard(props) {
    const url = props.pokemon.url;
    const pokemonIndex = url.split("/")[url.split("/").length - 2];
    const imageUrl = `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/home/${pokemonIndex}.png`;

    const [pokemonData, setPokemonData] = useState(undefined);
    const [pokemonType, setPokemonType] = useState(undefined);

    const getPokemonData = async () => {
        try {
            const res = await axios.get(url);
            setPokemonData(res.data);
            setPokemonType(res.data.types[0]?.type?.name);
        } catch (err) {}
    };
    useEffect(() => {
        getPokemonData();
    }, []);

    return (
        <View key={props.pokemon.name}>
            <Text>{props.pokemon.name}</Text>
            <View>
                {pokemonData && (
                    <Image
                        style={[
                            { height: 100 },
                            {
                                backgroundColor: typeToColor(pokemonType),
                            },
                        ]}
                        source={{
                            uri: imageUrl,
                        }}
                    />
                )}
            </View>
        </View>
    );
}

和 pokdex 文件

const [pokemon, setPokemon] = useState([]);
    const [currentPageUrl, setCurrentPageUrl] = useState(
        "https://pokeapi.co/api/v2/pokemon"
    );
    const [nextPageUrl, setNextPageUrl] = useState();
    const [prevPageUrl, setPrevPageUrl] = useState();

    const getDataFromApi = async () => {
        let cancel;
        const res = await axios.get("https://pokeapi.co/api/v2/pokemon", {
            cancelToken: new axios.CancelToken((c) => (cancel = c)),
        });
        const data = await res.data.results;

        setPokemon(data);

        return () => cancel();
    };

    useEffect(() => {
        getDataFromApi();
    }, [currentPageUrl]);

    return (
        <View
            style={{ flex: 1, justifyContent: "center", alignItems: "center" }}
        >
            <View>
                {pokemon.map((item) => (
                    <Pokecard pokemon={item} />
                ))}
                {/* <Pokelist pokemon={pokemon} /> */}
            </View>
        </View>
    );

不包括样式,可能需要进行一些其他编辑,例如使用 try catch 包装您的 axios 调用以处理失败,但这应该让您走上正轨