我正在尝试使用PokeAPI在React中制作Pokemon卡。我希望这些卡片具有2面,正面和背面具有扩展的细节。由于API端点的工作方式,每个单独的Pokemon都必须对其特定端点进行调用以获取扩展的详细信息。现在,我正在使用初始api调用(在componentDidMount内部)设置状态,该调用将返回口袋妖怪的详细列表,包括它们的名称和API端点url。此状态存储在名为“ Cardcontainer”的基于类的容器中,该容器具有2个功能组件“ frontCard”和“ backCard”,这些功能组件使用道具进行渲染。通过Cardcontainer组件上的click事件,通过HTTP请求检索backCard数据,该卡将被翻转以显示详细信息。一切正常,但是我无法获取详细信息以找到正确的卡片。我可以用咖喱粉来解决我的问题吗?无论如何,我都希望保留当前的设计,但是我可以使用currying来获取componentDidMount方法中的所有详细信息吗?您将如何解决这个问题?
卡片容器:
import React, { Component } from 'react';
import Frontcard from '../Components/frontCard';
import Backcard from '../Components/backCard';
class Cardcontainer extends Component {
state= {
pokemon: [],
cardBack: []
}
componentDidMount() {
const xhr = new XMLHttpRequest();
const url = 'https://pokeapi.co/api/v2/pokemon';
xhr.onload = () => {
if(xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
const pokeList = data.results;
this.setState(
{ ...this.state,
pokemon: pokeList,
}
)
}
else {
console.log('not ok')
}
}
xhr.open('GET', url, true);
xhr.send();
}
handleClick = (e) => {
const xhr = new XMLHttpRequest();
const url = `https://pokeapi.co/api/v2/pokemon/${e.currentTarget.firstChild.innerText}`;
xhr.onload = () => {
const backData = JSON.parse(xhr.responseText);
const joined = this.state.cardBack.concat(backData)
this.setState(
{
...this.state,
cardBack: joined
}
);
}
xhr.open('GET', url, true);
xhr.send();
}
render() {
return (
this.state.pokemon.map((poke, index)=>{
return (
<div onClick={this.handleClick}
className={"card-container"}
key={index}
>
<Frontcard name=
{this.state.pokemon[index].name}/>
<Backcard frontName=
{this.state.pokemon[index].name} number={index} name=
{this.state.cardBack[index]} />
</div>
)
})
)
}
}
export default Cardcontainer;
backcard:
import React from 'react';
const Backcard = (props) => {
const details = props;
console.log(!details.name? 'hi':details.name.name)
console.log()
return (
<div className={"card-back"}>
<h4>{details.name!==props.frontName? 'hi':
details.name.name}</h4>
</div>
)
}
export default Backcard;
如果我正确理解了您的问题,则每个口袋妖怪特定数据(您在背板组件中显示的数据)都有一个端点。
如果您真的不想在React组件中进行任何更改,则应该在第一次之后,通过调用组件中的n次遍历每个神奇宝贝的每个特定端点(坏主意)来馈送this.state.cardback数组从中获取宠物小精灵的列表,从中可以获取每个宠物小精灵的后续网址。
我的建议是将数据保存在Cardback组件本身中,因此它具有自己的状态,您将url作为prop传递,然后在componentDidMount方法的Cardback组件内部获取相应的数据。
我不确定您使用Currying是什么意思。 Currying是一个函数返回另一个可以在不同时间执行的函数的概念,它具有父函数变量的快照。
遇到问题,在同一组件中获取该组件所需的数据是一个好主意。您应该将Pokemon ID或url传递给backCard组件,然后在其中执行REST调用,以使用钩子获取数据并填充该组件。
我刚刚检查了https://pokeapi.co/api/v2/pokemon api,您能否将URL作为prop传递给backCard组件。
CardContainer:
import React, { Component } from 'react';
import Frontcard from '../Components/frontCard';
import Backcard from '../Components/backCard';
class Cardcontainer extends Component {
state= {
pokemon: [],
cardBack: []
}
componentDidMount() {
const xhr = new XMLHttpRequest();
const url = 'https://pokeapi.co/api/v2/pokemon';
xhr.onload = () => {
if(xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
const pokeList = data.results;
this.setState(
{ ...this.state,
pokemon: pokeList,
}
)
}
else {
console.log('not ok')
}
}
xhr.open('GET', url, true);
xhr.send();
}
render() {
return (
this.state.pokemon.map((poke, index)=>{
return (
<div className={"card-container"}
key={index}
>
<Frontcard name=
{this.state.pokemon[index].name}/>
<Backcard frontName=
{poke.name} number={index} name=
{poke.name} url={poke.url} />
</div>
)
})
)
}
}
export default Cardcontainer;
backCard
import React, { useState, useEffect } from 'react';
const Backcard = (props) => {
const [data, setData] = useState({});
useEffect(() => {
const xhr = new XMLHttpRequest();
xhr.onload = () => {
const backData = JSON.parse(xhr.responseText);
const joined = this.state.cardBack.concat(backData)
setData(joined);
}
xhr.open('GET', this.props.url, true);
xhr.send();
}, []);
const details = props;
console.log(!details.name? 'hi':details.name.name)
console.log()
return (
<div className={"card-back"}>
<h4>{details.name!==props.frontName? 'hi':
details.name.name}</h4>
</div>
)
}
export default Backcard;