Pinncik
Pinncik

Reputation: 321

React router - set correctly useParams for detail page

Probably this will be some small mistake but I really can't find out why it's not working.

I have react app and when It's initialized, it gets data from Pokéapi a set it to redux state.

While getting this data, <Intro /> component is shown. If downloading is over, page will redirect to /home and listPokemons component will render some of the results like this.

Main view - listPokemons

 result =  allPokemons.slice(0,9).map( (pokemon,i) => 

 <Link to={`/pokemon/${pokemon.id}`}>
    <Pokemon 
        key={i} 
        name={pokemon.name} 
        image={pokemon.image}
        type={pokemon.type}
        abilities={pokemon.abilities}
     />
 </Link>

So after click on some of the rendered Pokemons, location will change to /pokemon/id of pokemon.. This part is working.

In my app.js

<Router>
   {isLoading ? <Redirect exact to="/intro" /> : <Redirect exact from="/" to="/home" />}

   <Route exact path="/intro">
         <IntroView />
   </Route>

   <Route exact path="/home">
        <MainView />
   </Route>

   <Route path="/pokemon/:id">
       <PokemonOverview />
   </Route>
</Router>

So If I understand It right, if one of the pokemons is clicked, <PokemonOverview /> will render and is supposed to display data for that clicked pokemon. But it's not working.

PokemonOverview component

import React from 'react';
import {useParams} from "react-router-dom";

import {useSelector} from 'react-redux';

const PokemonOverview = () =>{
    const allPokemons = useSelector(state => state.AllPokemons);
    const {id} = useParams();
    const thisPokemon = allPokemons.map(pokemon => pokemon.id === id)

    return(
        <div>
            <h1>{thisPokemon.name}</h1>
        </div>
    )
}

export default PokemonOverview;

I don't know if this approach is correct but I'm not receiving any data in this component. I've followed some tutorials on youtube and everybody did this the same way. If I've tried to change value of <h1> for example to ' hello there ' ,it displays correctly after click on one of the listed pokemons..

What Am I doing wrong? Please help me someone . I'm looking everywhere and can't find anything how to do that :/

Upvotes: 0

Views: 1730

Answers (2)

Wenlong Jiang
Wenlong Jiang

Reputation: 802

First, please check what are you getting for "id", at const {id} = useParams();.

Then, please check what is "allPokemons" you get from const allPokemons = useSelector(state => state.AllPokemons);. If "allPokemons” is an Object then const thisPokemon = allPokemons.map(pokemon => pokemon.id === id) won't work proper. This map logic only works if "allPokemons" is an Array.

At last, please check the data type for "id" in pokemon.id === id. The "id" could be a string type, but if "pokemon.id" is a number type then the check will fail, event when "id" is correct. For example, 10 === "10" is false. If this is the case you can wrap "id" with parseInt(id) function.

Upvotes: 1

qasimmehdi
qasimmehdi

Reputation: 376

Try

allPokemons.find(pokemon => pokemon.id === id)

Edit: map and filter will always return an array. So if we want just one item we should use array.find

Upvotes: 0

Related Questions