You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目中基于public目录data.json实现动态路由的问题

解决React中从public目录data.json加载对应ID房产数据的问题

你现在的核心问题是:虽然通过useParams拿到了路由里的id,但没从加载的完整数据数组里筛选出对应项;而且之前尝试在fetch的URL后拼接id是行不通的——因为你的data.json是存储所有房产的数组文件,并非按ID拆分的单个文件。

具体修改步骤

  • 调整状态定义:不需要存储整个房产数组,直接存单个匹配的房产对象,初始值设为null便于判断加载状态。
  • 筛选匹配数据:在fetch成功后,用Array.find()方法根据路由id筛选对应项,注意useParams返回的id是字符串,要转成数字和data.json里的数字ID匹配。
  • 更新依赖项:把id加入useEffect的依赖数组,确保路由ID变化时重新筛选数据。
  • 处理渲染边界:渲染前先判断数据是否存在,避免出现Cannot read properties of null的错误。

修改后的RentalPage.jsx完整代码

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";

const RentalPage = () => {
  const { id } = useParams();
  // 存储单个匹配的房产数据,初始为null
  const [property, setProperty] = useState(null);

  const getData = () => {
    fetch("/data.json", {
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    })
      .then(response => response.json())
      .then(myJson => {
        // 将路由id转为数字,匹配对应房产
        const matchedProperty = myJson.find(item => item.id === Number(id));
        setProperty(matchedProperty);
      });
  };

  // 路由id变化时重新执行数据获取逻辑
  useEffect(() => {
    getData();
  }, [id]);

  return (
    <>
      {property ? (
        <h1>{property.name}</h1>
      ) : (
        <p>加载中...</p>
      )}
    </>
  );
};

export default RentalPage;

可选优化方案(减少重复请求)

如果想避免每次进入详情页都重新请求整个data.json,可以在列表页跳转时直接把房产数据通过路由状态传过去:

  1. 修改Rentals.jsx中的Link:
<Link to={`/rentals/${property.id}`} state={{ property }}>BOOK NOW</Link>
  1. 修改RentalPage.jsx,优先使用路由状态的数据,没有再去请求:
import { useEffect, useState } from "react";
import { useParams, useLocation } from "react-router-dom";

const RentalPage = () => {
  const { id } = useParams();
  const location = useLocation();
  // 优先用路由状态传过来的数据,没有则初始为null
  const [property, setProperty] = useState(location.state?.property || null);

  const getData = () => {
    fetch("/data.json", {
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    })
      .then(response => response.json())
      .then(myJson => {
        const matchedProperty = myJson.find(item => item.id === Number(id));
        setProperty(matchedProperty);
      });
  };

  // 只有当没有路由状态数据时才请求
  useEffect(() => {
    if (!property) {
      getData();
    }
  }, [id, property]);

  return (
    <>
      {property ? (
        <h1>{property.name}</h1>
      ) : (
        <p>加载中...</p>
      )}
    </>
  );
};

export default RentalPage;

内容的提问来源于stack exchange,提问作者jonteal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:40:34