#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.