redux Pokemon API支持rdx query和react:无法读取未定义的属性

23c0lvtd  于 12个月前  发布在  React
关注(0)|答案(2)|浏览(87)

我一直在尝试在浏览器中显示来自口袋妖怪API的数据,特别是体重、身高、名字和精灵的数据。
不幸的是,当我试图Map它时,我总是得到一个错误。有人能告诉我如何做到这一点吗?我做错了什么?有人能教我怎么做吗?”
这是我的代码:

import React from "react";
import { useGetPokemonByNameQuery } from "../Api/pokemonApi";

function PokemonCard() {
  const { data, error, isLoading, isError } = useGetPokemonByNameQuery();
  console.log(data)

  return (
    <>
      <ul>
        {isLoading && '...Loading...'}
        {isError && error.message}
        {data.map((pokemon) => (
          <li key={pokemon.id}>{pokemon.name}</li>
        ))}
      </ul>
    </>
  );
}
  
export default PokemonCard;
const pokemonApi = createApi({
  reducerPath: "pokemonApi",
  baseQuery: fetchBaseQuery({
    baseUrl: "https://pokeapi.co/api/v2/",
  }),
  endpoints: (builder) => ({
    getPokemonByName: builder.query({
      query: () => `/pokemon`,
    }),
  }),
});       
  
export const { useGetPokemonByNameQuery } = pokemonApi;
export default pokemonApi;
import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import pokemonApi from '../Api/pokemonApi';

export const store = configureStore({
  reducer: {
    [pokemonApi.reducerPath]: pokemonApi.reducer
  },
  middleware: (getDefaultMiddleware) => {
    return getDefaultMiddleware().concat(pokemonApi.middleware);
  } 
});

setupListeners(store.dispatch);
import pokemonApi  from './Api/pokemonApi'
import { ApiProvider } from '@reduxjs/toolkit/query/react';
import PokemonCard from './Components/PokemonCard';

function App() {
  return (
    <ApiProvider api={pokemonApi}>
      <div className="App">
        <h1>Pokemon</h1>
        <PokemonCard /> 
      </div>
    </ApiProvider>
  );
}

export default App;
oknrviil

oknrviil1#

问题

  • 你正在使用的口袋妖怪端点不返回数组,它返回一个具有results属性的数组对象。
// 20231009084854
// https://pokeapi.co/api/v2/pokemon

{
  "count": 1292,
  "next": "https://pokeapi.co/api/v2/pokemon?offset=20&limit=20",
  "previous": null,
  "results": [
    {
      "name": "bulbasaur",
      "url": "https://pokeapi.co/api/v2/pokemon/1/"
    },
    {
      "name": "ivysaur",
      "url": "https://pokeapi.co/api/v2/pokemon/2/"
    },
    ...,
    {
      "name": "raticate",
      "url": "https://pokeapi.co/api/v2/pokemon/20/"
    }
  ]
}
  • RTKQ钩子最初返回未定义的data,直到数据被获取和缓存。UI应该通过在任何data属性上使用空检查/保护子句或通过使用查询状态标志来解决这个问题,例如isSuccessisError等,以了解何时/是否有数据要渲染。

解决方案

简单的解决方案是在返回的data属性上使用空检查来访问results数组,例如。data?.results.map

function PokemonCard() {
  const { data, error, isLoading, isError } = useGetPokemonByNameQuery();

  return (
    <ul>
      {isLoading && "...Loading..."}
      {isError && error.message}
      {data?.results.map((pokemon) => (
        <li key={pokemon.name}>{pokemon.name}</li>
      ))}
    </ul>
  );
}

另一个简单的解决方案是转换响应。在获取和缓存任何数据之前,data仍然会有同样的问题。

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

const pokemonApi = createApi({
  reducerPath: "pokemonApi",
  baseQuery: fetchBaseQuery({
    baseUrl: "https://pokeapi.co/api/v2/"
  }),
  endpoints: (builder) => ({
    getPokemonByName: builder.query({
      query: () => "/pokemon",
      transformResponse: (response) => response.results
    })
  })
});

export const { useGetPokemonByNameQuery } = pokemonApi;
export default pokemonApi;
function PokemonCard() {
  const {
    data,
    error,
    isLoading,
    isError,
    isSuccess
  } = useGetPokemonByNameQuery();

  return (
    <ul>
      {isLoading && "...Loading..."}
      {isError && error.message}
      {isSuccess &&
        data.map((pokemon) => <li key={pokemon.name}>{pokemon.name}</li>)}
    </ul>
  );
}

Demo

biswetbf

biswetbf2#

尝试使用react query调用您的API,从API获取数据,然后将数据转换为JSON对象,如下所示:

const {data, isLoading,error} = useQuery('data',async() => {
const response = await fetch('api url')
return response.json()
});
return (
 <>
  <ul>
    {isLoading && '...Loading...'}
    {isError && error.message}
    {data.map((pokemon) => (
    <li key={pokemon.id}>{pokemon.name}</li>
  ))}
  </ul>
 </>
);

相关问题