繁体   English   中英

我可以在 React 中使用柯里化来进行后续的 API 调用吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM