Pokeapi pokemonDetails.map 不是函數且已修復 [模塊 '"react-router-dom"' 沒有導出成員 'RouteComponentProps' ]

salia_in_red

我正在使用 React 和 TypeScript 處理 Pokeapi。在獲取數據以在一側顯示所有 Pokemon 時,一切正常。但是當單擊特定的口袋妖怪以顯示其詳細信息時,我收到 2 個錯誤。

更新:已修復!#1 錯誤:我不能使用 {match},因為模塊 '"react-router-dom"' 沒有導出成員 'RouteComponentProps'。幾個月前我在 ReactJS 項目中使用了它,一切正常。

#2 錯誤:當映射拋出每個 Pokemon 時,會出現錯誤 pokemonDetails.map is not a function,而在另一個組件中使用 map 時(在一頁上顯示所有 Pokemon),一切正常。

這是我使用路由器的App.js 組件

import Pokedex from './Pokedex';
import Pokemon from './Pokemon';
import { Route, Routes } from 'react-router-dom';

function App() {
  return (
    <Routes>
      <Route path='/' element={<Pokedex />} />
      <Route path='/pokemon/:id' element={<Pokemon />} />
    </Routes>
  );
}

export default App;

這是我的Pokedex 組件(在一側顯示所有 Pokemon):

import { useEffect, useState } from 'react';
import Container from 'react-bootstrap/Container';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';

const Pokedex = () => {
  const [pokemon, setPokemon] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    getPokedex();
  }, []);

  const getPokedex = async () => {
    try {
      const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=151');
      const { results } = await res.json();
      const pokedex = results.map((pokemon: any, index: number) => {
        const paddedId = ('00' + (index + 1)).slice(-3);
        const image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
        return { ...pokemon, image };
      });
      setPokemon(pokedex);
      setLoading(false);
    } catch (err) {
      console.error(err);
    }
  };

  return (
    <Container>
      {loading ? (
        'Fetching Pokemon...'
      ) : (
        <Row>
          {pokemon.map((pokemon: any, index: number) => (
            <Col key={index} xs={1} sm={1} md={1} lg={1} xl={1}>
              <a href={`/pokemon/${index + 1}`}>
                <img src={pokemon.image} alt={pokemon.name} />
                <p>
                  {index + 1}.<span>{pokemon.name}</span>
                </p>
              </a>
            </Col>
          ))}
        </Row>
      )}
    </Container>
  );
};

export default Pokedex;

更新:這是Pokemon 組件(用於顯示每個 Pokemon 的詳細信息):

import { useEffect, useState } from 'react';
import Container from 'react-bootstrap/Container';
import { useParams } from 'react-router-dom';

const Pokemon = () => {
  const [pokemonDetails, setPokemonDetails] = useState();
  const [loading, setLoading] = useState(true);

  const { id } = useParams();

  useEffect(() => {
    getPokemon(id);
  }, [id]);

  const getPokemon = async (id: string | undefined) => {
    try {
      const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
      const pokemon = await res.json();
      const paddedId = ('00' + id).slice(-3);
      pokemon.image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
      setPokemonDetails(pokemon);
      setLoading(false);
    } catch (err) {
      console.error(err);
    }
  };

  return (
    <Container>
      <h1>Pokemon</h1>
      {loading ? (
        'Fetching Pokemon...'
      ) : (
        <div>
          <h2>{pokemonDetails.name}</h2>
          <h2>{pokemonDetails.id}</h2>
          <img src={pokemonDetails.image} alt={pokemon.Detailsname} />
          <p>
            {pokemonDetails.types.map((type: any, index: number) => (
              <p key={index}>{type.type.name}</p>
            ))}
          </p>
        </div>
      )}
    </Container>
  );
};

export default Pokemon;

帶有“id”的 API 應該返回這個https://pokeapi.co/api/v2/pokemon/1

這是我的package.json 文件,以防您需要它:

  "name": "pokemon",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.0",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "@types/jest": "^27.0.3",
    "@types/node": "^16.11.11",
    "@types/react": "^17.0.37",
    "@types/react-dom": "^17.0.11",
    "@types/react-router-dom": "^5.3.2",
    "axios": "^0.24.0",
    "bootstrap": "^5.1.3",
    "react": "^17.0.2",
    "react-bootstrap": "^2.0.3",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.0.2",
    "react-scripts": "4.0.3",
    "typescript": "^4.5.2",
    "web-vitals": "^1.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
德魯里斯

react-router-domV6不再有路線道具即無historylocationmatch道具),如Route曾在RRDv5組件。在 v6 中,您應該使用 React 鉤子來訪問匹配路由的匹配參數。

  1. 使用Link組件而不是原始錨 ( <a />) 標籤鏈接到特定的 Pokemon 頁面。

    import { Link } from 'react-router-dom';
    
    ...
    
    {pokemon.map((pokemon: any, index: number) => (
      <Col key={index} xs={1} sm={1} md={1} lg={1} xl={1}>
        <Link to={`/pokemon/${index + 1}`}>
          <img src={pokemon.image} alt={pokemon.name} />
          <p>
            {index + 1}.<span>{pokemon.name}</span>
          </p>
        </Link>
      </Col>
    ))}
    
  2. 使用useParams鉤子id從路徑中獲取匹配的匹配參數。

    import { useParams } from 'react-router-dom';
    
    const Pokemon = () => {
      const [pokemonDetails, setPokemonDetails] = useState([]);
      const [loading, setLoading] = useState(true);
    
      const { id } = useParams();
    
      useEffect(() => {
        getPokemon(id);
      }, [id]);
    
      const getPokemon = async (id: number) => {
        try {
          const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
          const pokemon = await res.json();
          const paddedId = ('00' + id).slice(-3);
          pokemon.image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
          setPokemonDetails(pokemon);
          setLoading(false);
        } catch (err) {
          console.error(err);
        }
      };
    
      return (
        ...
      );
    };
    

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章