ReactJS:如何正确处理从food2fork API获取的数据?

时间:2019-03-24 21:28:21

标签: reactjs api asynchronous

我有一个使用ReactJS构建的应用程序。其目的是显示在food2fork API中搜索到的食谱。 我没有更新父组件状态的问题。单击应用程序中的“搜索”按钮后,将提取数据。 我的问题与将获取的数据作为道具发送到子组件以及根据当前搜索正确显示接收到的食谱有关。


handleChange仅用于处理输入。

handleSearch是我想要使用按钮的“ onClick”来显示从API提取的数据的方法。

获取的食谱应显示在“结果”组件中。

希望很清楚:)


除了仅将状态作为来自Parent组件的道具传递并在Child组件中使用它之外,我还尝试使用生命周期方法根据收到的道具更新Child状态-也许我没有正确使用它们...

父组件:

import React, { Component } from 'react';
import Results from './Results';

class Recipes extends Component {
    constructor(props){
        super(props);
        this.state = {
            search: '',
            recipes: []
        }
    }
    handleChange=e=>{
        this.setState({
            search: e.target.value
        })
    }


    handleSearch =()=>{
            if(this.state.search !== ''){
                const url = `https://www.food2fork.com/api/search?key=367d2d744696f9edff53ec5b33a1ce64&q=${this.state.search}`

                fetch(url)
                        .then(data => data.json())
                        .then(jsonData => {
                            this.setState((jsonData)=> {return {
                                recipes: jsonData}
                            })
                        })

            } else {
                console.log('empty')
            }
    }

    render() {
        return (
            <Wrapper>
                <SearchBar 
                    value={this.state.search} 
                    type='search' 
                    onChange={this.handleChange}>
                </SearchBar>
                <SearchButton onClick={this.handleSearch}>SEARCH</SearchButton>

                <Results recipes={this.state.search}/>

            </Wrapper>
        );
    }
}

export default Recipes;

CHILD COMPONENT'Results'应该接收更新的食谱列表作为道具并显示这些食谱。

import React from 'react';
import Recipe from './Recipe';

class Results extends React.Component {
    render(){
        return (
            <Container>
                <RecipesList>
                    {this.props.recipes.map(item => 
                            <Recipe 
                                f2fURL={item.f2f_url}
                                image={item.image_url}
                                publisher={item.publisher}
                                publisherURL={item.publisher_url}
                                recipeID={item.recipe_id}
                                source={item.source_url}
                                title={item.title}
                            />)}
                </RecipesList>
            </Container>
        );
    }
};

2 个答案:

答案 0 :(得分:0)

您的问题在这里

this.setState((jsonData)=> {return {
    recipes: jsonData}
})

在ajax响应中。

将此更改为

this.setState({recipes: jsonData});

这应该正确设置食谱对象。

答案 1 :(得分:0)

正如@yourfavoritedev所述,您对Results道具有错字。它应该是 recipes={this.state.recipes}代替recipes={this.state.search}

您还应该更改:

this.setState((jsonData)=> {return {
                                recipes: jsonData}
                            })

针对:

this.setState({ recipes: jsonData })

更新程序功能将类似于以下内容(文档here):

(state, props) => stateChange

因此,您在setState上使用的jsonData实际上是先前的状态,而不是来自api调用的数据。