[英]Can I use currying in React to make a subsequent API calls?
我正在尝试使用 PokeAPI 在 React 中制作 Pokemon 卡片。 我希望卡片有 2 个面,一个正面和一个带有扩展细节的背面。 由于 API 端点的工作方式,每个单独的 Pokemon 都必须调用其特定的端点以获取扩展的详细信息。 现在我正在使用初始 api 调用(在 componentDidMount 内部)设置状态,它返回一个非详细的 pokemon 列表,包括它们的名称和 API 端点 url。 此状态存储在名为“Cardcontainer”的基于类的容器中,该容器具有 2 个功能组件,“frontCard”和“backCard”,它们使用 props 呈现。 backCard 数据是通过 HTTP 请求对 Cardcontainer 组件的点击事件进行检索,然后卡片将被翻转,显示详细信息。 一切正常,但我无法获取有关正确卡片的详细信息。 我可以使用柯里化来解决我的问题吗? 无论如何,我都想保留当前的设计,但是我可以使用柯里化来获取 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;
背卡:
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;
如果我正确理解了您的问题,那么每个 pokemon 特定数据(您在 backcard 组件中显示的数据)都有一个端点。
如果你真的不想在你的 React 组件中做任何改变,你应该在第一次检索到每个 pokemon 的每个特定端点(坏主意)后,通过在组件 didmount 中调用 n 次来提供 this.state.cardback 数组口袋妖怪列表,您可以从中获取每个口袋妖怪的后续 url。
我的建议是将数据保存在 Cardback 组件本身中,因此它有自己的状态,您将 url 作为 prop 传递,然后在 componentDidMount 方法的 Cardback 组件中获取相应的数据。
我不确定你所说的使用咖喱是什么意思。 柯里化是一个函数返回另一个可以在不同时间点执行的函数的概念,它具有父函数变量的快照。
谈到您的问题,最好在同一组件中获取组件所需的数据。 您应该将 Pokemon id 或 url 传递给 backCard 组件,并在那里执行 REST 调用以使用钩子获取数据并填充组件。
我刚刚检查了https://pokeapi.co/api/v2/pokemon api,您能否将 URL 作为道具传递给 backCard 组件。
卡片容器:
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;
背卡
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.