Reputation: 169
I'm having issues with this web app im working on.
https://food-search-octavian.netlify.com/
Now, on the recipe page https://food-search-octavian.netlify.com/recipes my search doesn't actually work. It's binded to Enter key which works, the request itself works, but when I try to set the state to the new search, it doesn't update.
This is the code in the component:
this.state = {
recipes: [],
search: "chicken",
loading: false,
height: 0
};
this.getRecipes = this.getRecipes.bind(this);
this.changeActive = this.changeActive.bind(this);
}
componentDidMount() {
this.getRecipes(this.state.search);
}
componentDidUpdate(prevProps, prevState) {
if (prevState.search !== this.state.search) {
this.getRecipes(this.state.search);
}
}
changeActive(newSearch) {
this.setState({
search: newSearch
});
}
getRecipes = async e => {
this.setState({
loading: true
});
await recipesRequest(e).then(response => {
this.setState({
recipes: response,
loading: false
});
});
};
This is the code for the request:
const axios = require("axios");
const recipesRequest = param => {
let api_key = "*";
let api_id = "*";
return axios
.get(
`https://api.edamam.com/search?q=chicken&app_id=${api_id}&app_key=${api_key}`,
{
headers: {
"Content-Type": "application/json"
}
}
)
.then(function(response) {
return response.data.hits;
});
};
export default recipesRequest;
This is the component with the search that updates the active state in the first compomnent:
this.state = {
input: ""
};
this.checkInput = this.checkInput.bind(this);
this.newSearch = this.newSearch.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
}
checkInput(e) {
var value = e.target.value;
this.setState({
input: value
});
}
handleKeyDown = e => {
if (e.key === "Enter") {
console.log(e.key);
let choice = this.state.input;
this.newSearch(choice);
}
};
newSearch(choice) {
this.props.changeActive(choice);
this.setState({
input: ""
});
}
From what I read, setState is async but I kinda have the exact logic in the other page of my web app and it works.
Upvotes: 0
Views: 41
Reputation: 202618
I'm guessing it is your getRecipes
function. React's setState
is "asynchronous, but not in the javascript async/await sense. It is more like state updates during the current render cycle are queued up to be processed for the next render cycle.
getRecipes = async e => {
this.setState({
loading: true
});
await recipesRequest(e).then(response => {
this.setState({
recipes: response,
loading: false
});
});
};
Here you are awaiting the execution of the state updates you've queued up, which normally are processed after the function returns. Try not awaiting it.
getRecipes = e => {
this.setState({
loading: true
});
recipesRequest(e).then(response => {
this.setState({
recipes: response,
loading: false
});
});
};
This allows the fetch to occur, which is asynchronous, but it correctly allows the state updates to be queued. The state will update loading to be true, and returns the (likely) unresolved Promise, and when the request resolves (any number of render cycles later) it updates state again loading false and with the recipes.
EDIT In the codesandbox both ways work, so perhaps you are not receiving/processing response data correctly, or you have a malformed request.
Upvotes: 1