ReactJS: как правильно обрабатывать данные, полученные из food2fork API?

#reactjs #api #asynchronous

#reactjs #API #асинхронный

Вопрос:

У меня есть приложение, созданное с помощью ReactJS. Его назначение — отображать рецепты, которые были найдены в food2fork API. У меня нет проблем с обновлением состояния родительского компонента. Данные извлекаются после нажатия кнопки «поиск» в приложении. Моя проблема связана с отправкой выбранных данных в качестве реквизитов дочернему компоненту и правильным отображением полученных рецептов на основе текущего поиска.


handleChange предназначен только для обработки входных данных.

handleSearch — это то, что я хотел использовать ‘onClick’ кнопки для отображения данных, извлеченных из API.

Выбранные рецепты должны отображаться в компоненте результатов.

Надеюсь, это понятно 🙂


Помимо передачи состояния в качестве реквизита только из родительского компонента и использования его в дочернем компоненте, я также попытался обновить дочернее состояние на основе полученных реквизитов с помощью методов жизненного цикла — возможно, я не использовал их в настоящее время…

Родительский компонент:

 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=367d2d744696f9edff53ec5b33a1ce64amp;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;
  

ДОЧЕРНИЙ КОМПОНЕНТ ‘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>
        );
    }
};
  

Комментарии:

1. я думаю, у вас может быть опечатка. похоже, вы передаете this.state.search в качестве свойства дочернему компоненту. Вы должны передавать в этом.state.recipes 🙂

Ответ №1:

Как упоминал @yourfavoritedev, у вас опечатка в реквизитах результатов. Это должно быть recipes={this.state.recipes} вместо recipes={this.state.search}

Вам также следует изменить:

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

для:

 this.setState({ recipes: jsonData })
  

Функция обновления будет выглядеть примерно так (документация здесь):

 (state, props) => stateChange
  

Таким образом, jsonData вы используете в своем setState фактически предыдущее состояние, а не данные, поступающие из вызова api.

Комментарии:

1. я думаю, что это подводит итог всем проблемам, которые у меня были с этим. Большое вам спасибо за помощь. Теперь все работает правильно. this.state.search действительно была опечатка :). Я думаю, что я сделал это после одного из изменений, которые я пытался реализовать, чтобы заставить этот запрос работать.

Ответ №2:

Ваша проблема здесь

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

внутри вашего ответа ajax.

Измените это на

 this.setState({recipes: jsonData});
  

Это должно правильно настроить объект recipes.