When I try to run this code it returns "TypeError: state.drinksData.map is not a function". However, when I type manually the index (as state.drinksData[0]) it works fine. Why is that and how can I fix it?
import React, {useState} from 'react';
var initialState = {
drinksData: ""
}
function LoadDrinks(props) {
const [state, setState] = useState(initialState);
//Fetching the cocktails' data from the ingredient clicked
function pageReload(e){
fetch(`https://www.thecocktaildb.com/api/json/v1/1/filter.php?i=${e.target.value}`)
.then(res=>res.json())
.then(data=>{
setState({drinksData:data.drinks})
})
}
console.log(state.drinksData)
var drinkData = state.drinksData.map(data=>{return(data)});
//However, this code runs fine when I type the index manually --> drinkData = state.drinksData[0];
var ingredients = ["Gin", "Vodka", "Rum", "Whiskey", "Tequila", "Brandy"];
return (
<>
<select onChange={pageReload}>
{ingredients.map((ingredient, i)=>{return (<option key={i}>{ingredient}</option>)})}
</select>
<div>{drinkData.strDrink}</div>
</>
)
}
export default LoadDrinks;
This is part of my first React project. I appreciate your help:)
Don't mix the types of values in state when possible, otherwise you can get errors like these. You initially set drinksData
to a string, but the value given by the API in data.drinks
is an array.
Initialize the initial state to an empty array, not a string. (You can't .map
strings, hence the error.)
const initialState = {
drinksData: []
};
Also, the line here
var drinkData = state.drinksData.map(data=>{return(data)});
is completely superfluous: it creates a new array that's exactly the same as the old array. Feel free to remove it entirely and just keep using state.drinksData
.
strDrink
is a property of one of the objects in the array - it's not a property of the array, so drinkData.strDrink
or state.drinkData.strDrink
won't work. If you want to get to one of the object's strDrink
s, iterate over the array, eg
state.drinksData.map(obj => obj.strDrink)
Lastly, since you're using hooks, there's no reason to have an extra nested object in state. It'd be easier for the state to be just a plain array:
const [drinks, setDrinks] = useState([]);
and
function pageReload(e){
fetch(`https://www.thecocktaildb.com/api/json/v1/1/filter.php?i=${e.target.value}`)
.then(res=>res.json())
.then(data=>{
setDrinks(data.drinks);
})
// .catch(handleErrors); // don't forget to catch possible errors
}