我正在尝试创建一个图鉴应用程序。在我的 app.js 中,我使用 useEffect 进行 API 调用,然后使用子组件详细说明每张卡片。 我想要做的是当用户点击一张卡片时,app.js 检索选定的宠物小精灵的数据,稍后将用于打开模态并显示选定的宠物小精灵的信息。 在 app.js 上,我创建了一个 props handleClickparent,它是一个函数,可以从 PokemonCard compenent 控制台记录我的数据。
在 app.js 上:
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
import React, { useState, useEffect } from "react";
import PokemonCard from "./component/PokemonCard";
function App() {
const [pokemonList, setPokemonList] = useState([]);
const [findPokemon, setFindPokemon] = useState("");
const [pokemonInfos, setPokemonInfos] = useState(null);
//Function for API Call
const searchPokemon = async () => {
const rawData = await fetch("https://pokeapi.co/api/v2/pokemon?limit=150");
const data1 = await rawData.json();
const data2 = await Promise.all(
data1.results.map((data) =>
fetch(`https://pokeapi.co/api/v2/pokemon/${data.name}`).then((data) =>
data.json()
)
)
);
setPokemonList(data2);
};
//Console.log data from PokemonCard component
const getData = (pokemon) => {
return console.log(pokemon);
};
//Initialize component
useEffect(() => {
searchPokemon();
}, []);
return (
<div>
<h5 className="title">Pokedex</h5>
<div className="SearchBar">
<input
className="Input"
type="search"
placeholder="...Search Pokemon"
onChange={(e) => setFindPokemon(e.target.value)}
value={findPokemon}
></input>
</div>
<PokemonCard
pokemonList={pokemonList}
searchValue={findPokemon}
handleClickParent={getData}
/>
</div>
);
}
export default App;
PokemonCard 组件
import React, { useEffect, useState } from "react";
import "../App.css";
function PokemonCard({ pokemonList, searchValue }, props) {
//using Hook to change the value when the user is hovering or selecting on a card
const [IsHovering, setIsHovering] = useState(-1);
const [selectIndex, setSelectIndex] = useState(-1);
//On click I send the select pokemon infos to the parent component
const handleClick = (pokemon) => {
console.log(pokemon);
props.handleClickParent(pokemon);
};
return (
<div className="RowCard">
{pokemonList
.filter((pokemon) => {
return pokemon.name.match(searchValue);
})
.map((pokemon, i) => {
return (
<div
key={i}
className={`Card ${IsHovering === i ? "HoveringCard" : ""}`}
onMouseEnter={() => setIsHovering(i)}
onMouseLeave={() => setIsHovering(-1)}
onClick={() => handleClick(pokemon)}
>
<p>{pokemon.name}</p>
<img
className="ImgPokemon"
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/${pokemon.id}.png`}
></img>
</div>
);
})}
</div>
);
}
export default PokemonCard;
但是我的控制台上显示错误:
PokemonCard.js:13 Uncaught TypeError: props.handleClickParent is not a function
at handleClick (PokemonCard.js:13:1)
at onClick (PokemonCard.js:29:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1)
at executeDispatch (react-dom.development.js:9041:1)
at processDispatchQueueItemsInOrder (react-dom.development.js:9073:1)
at processDispatchQueue (react-dom.development.js:9086:1)
at dispatchEventsForPlugins (react-dom.development.js:9097:1)
h
如果有人看到我的代码有什么问题,如果你愿意分享你的想法,我会非常高兴。 提前致谢
您正在解构
pokemonList
和 searchValue
,但添加 props
作为组件的第二个参数。要么破坏你的handleClickParent
,要么只使用道具和props.pokemonList
(或其他道具)来访问你的道具。函数组件中通常没有第二个参数,除非您使用像 forwardRef
这样的东西,它会将 ref 添加为第二个参数。
function PokemonCard({ pokemonList, searchValue, handleCickParent }) {...}
或
function PokemonCard(props) {...}
问题似乎与您将 handleClickParent 函数传递给 PokemonCard 组件的方式有关。在 App.js 文件中,您将函数作为名为 handleClickParent 的道具传递,但在 PokemonCard.js 文件中,您正试图将其作为 props.handleClickParent 进行访问。
你应该替换这一行:
function PokemonCard({ pokemonList, searchValue }, props)
这个:
function PokemonCard({ pokemonList, searchValue, ...props })
使用“rest”运算符(...props)将收集传递给组件的任何其他道具并将它们存储在一个名为 props 的对象中,可以根据需要在组件主体中使用。
或者您可以从 PokemonCard 函数定义中删除 props 参数,直接使用 handleClickParent 即可:
function PokemonCard({ pokemonList, searchValue, handleClickParent }) {