我可以在React中使用currying进行后续的API调用吗?

问题描述 投票:0回答:2

我正在尝试使用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;
javascript reactjs currying
2个回答
0
投票

如果我正确理解了您的问题,则每个口袋妖怪特定数据(您在背板组件中显示的数据)都有一个端点。

如果您真的不想在React组件中进行任何更改,则应该在第一次之后,通过调用组件中的n次遍历每个神奇宝贝的每个特定端点(坏主意)来馈送this.state.cardback数组从中获取宠物小精灵的列表,从中可以获取每个宠物小精灵的后续网址。

我的建议是将数据保存在Cardback组件本身中,因此它具有自己的状态,您将url作为prop传递,然后在componentDidMount方法的Cardback组件内部获取相应的数据。


0
投票

我不确定您使用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;
© www.soinside.com 2019 - 2024. All rights reserved.