【问题标题】:React router - set correctly useParams for detail pageReact 路由器 - 为详细信息页面正确设置 useParams
【发布时间】:2020-12-12 18:55:48
【问题描述】:

这可能是一个小错误,但我真的不知道为什么它不起作用。

我有 react 应用程序,当它初始化时,它会从 Pokéapi 获取数据并将其设置为 redux 状态。

在获取此数据时,会显示<Intro /> 组件。如果下载结束,页面会重定向到/homelistPokemons组件会渲染一些这样的结果。

主视图 - 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>

所以点击一些渲染的口袋妖怪后,位置将变为口袋妖怪的/pokemon/id..这部分正在工作。

在我的 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>

所以如果我理解正确,如果点击了其中一个口袋妖怪,&lt;PokemonOverview /&gt; 将呈现并应该显示该点击的口袋妖怪的数据。但它不起作用。

PokemonOverview 组件

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;

我不知道这种方法是否正确,但我没有收到此组件中的任何数据。我在 youtube 上关注了一些教程,每个人都以同样的方式做到了这一点。如果我尝试将 &lt;h1&gt; 的值更改为“你好”,它会在单击列出的口袋妖怪之一后正确显示..

我做错了什么?请帮助我的人。我到处找,找不到任何方法:/

【问题讨论】:

  • 你能把console.log(allPokemons)console.log(id) 得到的结果贴出来吗?

标签: javascript reactjs routes react-router


【解决方案1】:

首先,请检查您在const {id} = useParams(); 获得的“id”。

那么,请检查您从const allPokemons = useSelector(state =&gt; state.AllPokemons); 获得的“allPokemons”是什么。如果“allPokemons”是一个对象,那么const thisPokemon = allPokemons.map(pokemon =&gt; pokemon.id === id) 将无法正常工作。此映射逻辑仅在“allPokemons”是一个数组时才有效。

最后,请检查pokemon.id === id中“id”的数据类型。 “id”可以是字符串类型,但如果“pokemon.id”是数字类型,则检查将失败,“id”正确时的事件。例如,10 === "10"false。如果是这种情况,您可以使用 parseInt(id) 函数包装“id”。

【讨论】:

  • 谢谢你的回答,我一上电脑我就试试。似乎我并不清楚 useparams 是做什么的。如果我做对了,它需要当前的 url,例如 /pokemon/3 ,所以 {Id} = useparams 将是 3?或者我应该如何传递那个 Id ?谢谢。
  • 我高度怀疑 id 是字符串类型。您可以尝试打印出pokemon.id === id 的结果和id 的值。由于“id”是从 url 获取的,它可能是“3”(字符串)而不是 3(数字),这将使“===”失败。
  • 我马上试试,我会告诉你的。
  • 你是对的,{id}​​ 是字符串,来自 allPokemons 的 id 是数字。谢谢你。但我还有另一个问题。如果我点击 pokemon,url 会发生变化,但他的信息会显示在列出的 pokemon 下。我的意思是列出的口袋妖怪组件不会卸载
  • @Pinncik 抱歉回复晚了。问题解决了吗?
【解决方案2】:

试试

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

编辑: map 和 filter 将始终返回一个数组。因此,如果我们只想要一项,我们应该使用 array.find

【讨论】:

  • 返回空数组
  • 你能添加一个口袋妖怪数组的样本吗?
  • 返回未定义的:/
  • 你的意思是说所有口袋妖怪在哪里?当然,{id(pin):10 name(pin):"Caterpie" image(pin):"raw.githubusercontent.com/PokeAPI/sprites/master/sprites/…" type(pin):"bug"}
  • @Pinncik 你检查过你是否正确获取了 id 的值吗?
猜你喜欢
  • 1970-01-01
  • 2014-01-02
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2020-11-29
  • 1970-01-01
  • 2014-12-15
相关资源
最近更新 更多