I'll start by saying I've gone through this page and I don't see any reason why I will be getting this error, my versions are all fine and I don't have duplicate Reacts.
The error is thrown when I click on a card.
This is my App.js:
const App = () => {
const [inputString, setInputString] = useState("") //Error points to here
const updateInput = (e) => {
const lowerString = e.target.value.toLowerCase();
setInputString(lowerString);
}
return (
<>
<div className='search-bar-container'>
<img src='https://cdn-icons.flaticon.com/png/512/868/premium/868596.png?token=exp=1647880908~hmac=5e802c3c8b8423596716ca9353212d17' className='poke-ball-img' />
<input type='text' placeholder='Search For a Pokemon!' onChange={updateInput}></input>
</div>
<div className='card-container'>
<RenderPokemon input={inputString} />
</div>
</>
);
}
export default App;
And this is RenderPokemon:
const RenderPokemon = (text) => {
const [rawPokemonList, setRawPokemonList] = useState([]);
const getPokemonData = async (id) => {
//Move this out somehow, to avoid calling on every render
try {
const res = await fetch("https://pokeapi.co/api/v2/pokemon/" id);
const pokemon = await res.json();
return pokemon;
} catch (e) {
console.log(e);
}
};
const sortPokemonList = rawPokemonList.filter((poke) => {
if(text.input === "") {
return poke;
} else {
return poke.name.toLowerCase().includes(text.input)
}
})
useEffect((i) => {
const promises = [];
for (let i = 1; i < 152; i ) {
promises.push(getPokemonData(i));
}
Promise.all(promises).then((results)=>{
setRawPokemonList(results);
})
}, []);
return (
(sortPokemonList).map(poke=>(
<div className='card' onClick={updatePokemonId} id={poke.id}>
<img src={'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/' poke.id '.svg'} className='PokeImg' key={poke.id} id={poke.id}/>
<div className='container'>
<p>{poke.name}</p>
</div>
</div>
))
)
}
export default RenderPokemon;
CodePudding user response:
first thing :
<input **value =inputString** type='text' placeholder='Search For a Pokemon!'
onChange={updateInput}></input>
CodePudding user response:
@GuyMate here is my review:
- first you should pass updatePokemonId to RenderPokemon Component.
- Second
e.target.value
will always be undefined becausediv
tags dont have values. only special html tags likeinputs
have value property.
So change the code of updateInput
to update using the id
:
const updateInput = (e) => {
const id= e.target.id.toLowerCase();
setInputString(lowerString);
}
Then you should pass it to the RenderPokemon
component:
<RenderPokemon input={inputString} updatePokemonId={updatePokemonId}/>
then you should use it the RenderPokemon
component and use the name of the pokemon as id because each pokemon has unique id:
const RenderPokemon = ({ input, updatePokemonId }) => {
const [rawPokemonList, setRawPokemonList] = useState([]);
const getPokemonData = async (id) => {
//Move this out somehow, to avoid calling on every render
try {
const res = await fetch("https://pokeapi.co/api/v2/pokemon/" id);
const pokemon = await res.json();
return pokemon;
} catch (e) {
console.log(e);
}
};
const sortPokemonList = rawPokemonList.filter((poke) => {
if(input === "") {
return poke;
} else {
return poke.name.toLowerCase().includes(input)
}
})
useEffect((i) => {
const promises = [];
for (let i = 1; i < 152; i ) {
promises.push(getPokemonData(i));
}
Promise.all(promises).then((results)=>{
setRawPokemonList(results);
})
}, []);
return (
(sortPokemonList).map(poke=>(
<div className='card' onClick={updatePokemonId} id={poke.name}>
<img src={'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/' poke.id '.svg'} className='PokeImg' key={poke.id} id={poke.id}/>
<div className='container'>
<p>{poke.name}</p>
</div>
</div>
))
)
}
export default RenderPokemon;