【问题标题】:React useParams gives empty object when goes to pageReact useParams 在进入页面时给出空对象
【发布时间】:2022-01-01 15:25:18
【问题描述】:

我正在做一个个人React.js 项目。我遇到了useParams 的问题。单击导航栏后,我无法显示地图项。它进入页面,但无法在屏幕上显示。它在屏幕上显示一个空对象。这是我定义useParamsItemContainer,我认为代码有错误:

import { useEffect, useState } from "react";

import ItemDetails from "../Itemdetails";
import { useParams } from "react-router-dom";

const ItemContainer = () => {
  const [venue, setVenue] = useState({});
  const { raceId } = useParams();

  useEffect(() => {
    fetch("https://www.betright.com.au/api/racing/todaysracing")
      .then((res) => {
        return res.json();
      })
      .then(
        (data) => {
            setVenue(data);
          console.log("data useEffect", data);
        },
        (err) => {
          return console.error(err);
        }
      );
  }, []);
  console.log("venue container", {venue});

  const para = Object.keys(venue).find((findKey) => findKey === raceId);
  console.log('para', para)

  return (
      <ItemDetails key={para} venue={venue} />
  );
};

export default ItemContainer;

这是我要在其中显示项目的ItemDetails

const ItemDetails = ({ venue }) => {
    console.log('venue itemDetails', venue)
    return (
        <> 
        {venue.slice(0, 5).map(races => (
            <>
            <p>{races.Venue}</p>
            <p>Race Number: {races.Race1?.RaceNumber}</p>
            </>
        ))}
        </>
    );
}
 
export default ItemDetails;

这是导航栏:

import { useEffect, useState } from "react";

import { NavLink } from "react-router-dom";
import styles from './Navbar.module.css';

const Navbar = () => {
    const [result, setResult] = useState([]);

    useEffect(() => {
      fetch("https://www.betright.com.au/api/racing/todaysracing")
        .then((res) => {
          return res.json();
        })
        .then(
          (data) => {
            setResult(data);
            console.log("data useEffect", data);
          },
          (err) => {
            return console.error(err);
          }
        );
    }, []);
    console.log("result of Navbar", result);
    
    return (
        <>            
            <div className={styles.navbarContainer}>
                <NavLink to='./races' 
                className={styles.navbarHome} 
                style={({ isActive }) => ({
                  color: isActive ? '#fff' : '#f4f4f4',
                  background: isActive ? '#7600dc' : '#7600dc',
                })}>Home</NavLink>
                {Object.entries(result).map(([key, value]) => (
                    <div className={styles.navbarItems} key={key}>
                        {value.slice(0, 1).map((i, race) => (
                            <NavLink 
                                key={i}
                                to={`/race/${key}`}
                                style={({ isActive }) => ({
                                    color: isActive ? '#fff' : '#d3d3d3',
                                    background: isActive ? '#7600dc' : '#7600dc',
                                    textDecoration: isActive ? 'none' : 'none'
                                    })}>{key}</NavLink>
                        ))}                            
                    </div>                                  
                ))}
            </div>
        </>
    );
}
 
export default Navbar;

这是 App.js

const App = () => {
  return (
    <>
        <Router>
            <Navbar />
            <Routes>
                <Route path='/races' element={<Home />} />
                <Route path="/" element={<Navigate replace to="/races" />} />
                <Route path="/race/:raceId" element={<ItemContainer />} />
            </Routes> 
        </Router>
        
    </>
  )
}

这是一个 link 到包含整个代码的代码框。

更新

这是数据的模拟。 API的原始值具有所有不同的值,只有Throughbred,Harness和Greyhound的键是找到的useParams的共同点。这是一个新的link with the whole code plus the data mocked。您还可以在下面找到模型数据:

    const data = {
      Throughbred: [
        {
            VenueID: 674,
            Venue: "Santa Anita Park",
            Race1: {
              EventTypeId: 1,
              EventId: 6177745,
              VenueId: 0,
              Venue: null,
              CountryCode: null,
              RaceNumber: 6,
              AdvertisedStartTime: "/Date(1641036900000)/",
              ResultStatusId: 0,
              SecondsToJump: 609,
              HasFixedMarkets: false,
              IsOpenForBetting: false,
              MarketShortcuts: null,
              Results: null,
              MasterCategoryName: null,
              EventName: null,
            },
            CountryCode: "USA",
            MasterCategoryName: "Overseas-Racing",
          },
          {
            VenueID: 674,
            Venue: "Santa Anita Park",
            Race1: {
              EventTypeId: 1,
              EventId: 6177745,
              VenueId: 0,
              Venue: null,
              CountryCode: null,
              RaceNumber: 6,
              AdvertisedStartTime: "/Date(1641036900000)/",
              ResultStatusId: 0,
              SecondsToJump: 609,
              HasFixedMarkets: false,
              IsOpenForBetting: false,
              MarketShortcuts: null,
              Results: null,
              MasterCategoryName: null,
              EventName: null,
            },
            CountryCode: "USA",
            MasterCategoryName: "Overseas-Racing",
          }
        ],
    
      Harness: [{
        VenueID: 674,
        Venue: "Santa Anita Park",
        Race1: {
          EventTypeId: 1,
          EventId: 6177745,
          VenueId: 0,
          Venue: null,
          CountryCode: null,
          RaceNumber: 6,
          AdvertisedStartTime: "/Date(1641036900000)/",
          ResultStatusId: 0,
          SecondsToJump: 609,
          HasFixedMarkets: false,
          IsOpenForBetting: false,
          MarketShortcuts: null,
          Results: null,
          MasterCategoryName: null,
          EventName: null,
        },
        CountryCode: "USA",
        MasterCategoryName: "Overseas-Racing",
      },
      {
        VenueID: 674,
        Venue: "Santa Anita Park",
        Race1: {
          EventTypeId: 1,
          EventId: 6177745,
          VenueId: 0,
          Venue: null,
          CountryCode: null,
          RaceNumber: 6,
          AdvertisedStartTime: "/Date(1641036900000)/",
          ResultStatusId: 0,
          SecondsToJump: 609,
          HasFixedMarkets: false,
          IsOpenForBetting: false,
          MarketShortcuts: null,
          Results: null,
          MasterCategoryName: null,
          EventName: null,
        },
        CountryCode: "USA",
        MasterCategoryName: "Overseas-Racing",
      }
    ],
      Greyhound: [
        {
            VenueID: 674,
            Venue: "Santa Anita Park",
            Race1: {
              EventTypeId: 1,
              EventId: 6177745,
              VenueId: 0,
              Venue: null,
              CountryCode: null,
              RaceNumber: 6,
              AdvertisedStartTime: "/Date(1641036900000)/",
              ResultStatusId: 0,
              SecondsToJump: 609,
              HasFixedMarkets: false,
              IsOpenForBetting: false,
              MarketShortcuts: null,
              Results: null,
              MasterCategoryName: null,
              EventName: null,
            },
            CountryCode: "USA",
            MasterCategoryName: "Overseas-Racing",
          },
          {
            VenueID: 674,
            Venue: "Santa Anita Park",
            Race1: {
              EventTypeId: 1,
              EventId: 6177745,
              VenueId: 0,
              Venue: null,
              CountryCode: null,
              RaceNumber: 6,
              AdvertisedStartTime: "/Date(1641036900000)/",
              ResultStatusId: 0,
              SecondsToJump: 609,
              HasFixedMarkets: false,
              IsOpenForBetting: false,
              MarketShortcuts: null,
              Results: null,
              MasterCategoryName: null,
              EventName: null,
            },
            CountryCode: "USA",
            MasterCategoryName: "Overseas-Racing",
          }
        ]
}
export default data;

另外,这是console.log(result) 的截图

【问题讨论】:

  • Codesandbox 不适合我,API 返回错误
  • 嗨@LuisMontoya 我刚刚检查过,它工作正常。这是同一个链接:codesandbox.io/s/festive-vaughan-070ug
  • 您在哪个页面有问题? /race/:raceId ?
  • @JoaquinPalacios 我和 Luis 有同样的问题,我在 api 上得到了空结果。我猜,我们还在 1 月 1 日,但你在澳大利亚已经搬到 1 月 2 日了?所以/racing/todaysracing 没有结果。
  • CSB 不起作用,您的 API 端点似乎受到限制,因此它不会为我们提取任何数据。 raceId 路由参数正在工作,所以我只能假设它是 API 未返回数据或您的 Object.keys(venue).find((findKey) =&gt; findKey === raceId) 逻辑不正确。您可以在 CSB 中为我们模拟 "https://www.betright.com.au/api/racing/todaysracing" 数据响应,我们可以从那里进行调试。

标签: javascript reactjs object react-router react-router-dom


【解决方案1】:

您在处理响应数据方面存在一些问题。

导航栏

数据是一个对象,其中每个属性都是一个键(种族分类?),其值是场地数组。只需将键映射到链接。

{Object.keys(result).map((key) => (
  <div className={styles.navbarItems} key={key}>
    <NavLink
      to={`/race/${key}`}
      style={({ isActive }) => ({
        color: isActive ? "#fff" : "#d3d3d3",
        background: isActive ? "#7600dc" : "#7600dc",
        textDecoration: isActive ? "none" : "none"
      })}
    >
      {key}
    </NavLink>
  </div>
))}

物品容器

假设fetch 功能正确并且venues 状态更新为正确的值,这里的问题是您只搜索键,只返回键而不是数组值。在这里,您可以简单地使用raceId 作为访问场地数组的动态键。

const para = venues[raceId] ?? [];

...

return para.map((venue) => <ItemDetails key={venue.VenueID} venue={venue} />);

【讨论】:

  • 嗨,德鲁。谢谢你的帮助。不幸的是,它不起作用。导航栏按照我的方式工作得很好。我的意思是,它转到 /race/greyhound 或其他任何一个。当我尝试您的代码时,它会破坏代码。
  • 嗨,德鲁。我道歉。我仔细检查了数据的模拟,它有一个错误。现在已经修好了。整个数据是一个对象。
  • @JoaquinPalacios 好的,更新了我的答案和 CSB。如果可以的话,请再看看。
  • 谢谢德鲁。导航栏完美运行,但是当我单击导航栏的某个项目时,它会随着 itemcontainer 的更改而崩溃。如果我不修改 Itemcontainer,它会像以前一样工作。屏幕上的错误显示:TypeError Cannot read properties of undefined (reading 'map')。此外,'para' 的 console.log 是未定义的
  • Throughbred、Harness 和 Greyhound 中的每一个都有许多阵列。因此,想法是根据用户点击的内容,在屏幕 (ItemDetail) 中显示Throughbred、Harness 或 Greyhound 的所有内容。因为那个 VenueID 不起作用,我正在尝试使用密钥 Throughbred、Harness 和 Greyhound 来匹配 useParams 的raceId。
猜你喜欢
  • 2020-07-13
  • 2023-02-01
  • 2021-08-24
  • 2011-04-21
  • 2022-07-16
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多