【问题标题】:Dynamic route react-router-dom动态路由 react-router-dom
【发布时间】:2021-01-26 00:01:13
【问题描述】:

我想使用 react-router-dom 在我的 react 应用程序中创建一个动态路由。我一直在阅读有关它的文件,但在我的情况下,这些都没有真正意义。我有一个项目页面,然后您可以单击项目页面中的链接,它会将您带到一个名为项目详细信息的新页面。每个网址都不一样。

App.js

<BrowserRouter>
        <Switch>
            <Route path="/" component={Home} exact />
            <Route path="/about" component={About} exact />
            <Route path="/projects" component={Projects} exact />
            <Route path="/workshops" component={Workshops} exact />
            <Route path="/bodywork" component={Bodywork} exact />
            <Route path="/contact" component={Contact} exact />
            <Route path="/:projectdetails" component={ProjectDetails} exact />
        </Switch>
</BrowserRouter>

有十个不同的项目,名称各不相同。它们在这样的数据文件中:

export const ObjOne = {
    title: 'Feldbewegung',
    img: './images/bodyOfEarth.jpg',
    alt: 'Feldbewegung',
    link: '/feldbewegung-details'
};

export const ObjTwo = {
    title: 'Nonmaterial city beautification',
    img: './images/bodyOfEarth.jpg',
    alt: 'Nonmaterial city beautification',
    link: '/nonmaterial-city-beautification-details'
};

export const ObjThree= {
    title: 'Body of Earth',
    img: './images/bodyOfEarth.jpg',
    alt: 'Body of Earth',
    link: '/body-of-earth-details'
};

例如有三个。然后它们被传递到 Projects.js

import { ObjOne, ObjTwo, ObjThree, ObjFour, ObjFive, ObjSix, ObjSeven, ObjEight, ObjNine, ObjTen} from '../components/Data/projectsData';

function ProjectImage({img, alt, link, title}) {
    return (
        <>
        <div className="ProjectImage">
            <img className="project-img" src={img} alt={alt} />
            <a className="project-link" href={link}>{title}</a>
        </div>       
        </>
    )
}


function Projects({}) {
    return (
        <>
            <Navbar1 />
            <div className="page">
                <Container className="projects-container">
                    <ProjectImage {...ObjOne} />
                    <ProjectImage {...ObjTwo} />
                    <ProjectImage {...ObjThree} />


...continuing to ObjTen..

有没有办法以某种方式添加动态路由或页面?

【问题讨论】:

    标签: reactjs react-router-dom dynamic-url dynamic-pages


    【解决方案1】:

    有多种方法可以处理此问题。它们可以是单独的路由,但不一定是,因为它们都使用相同的渲染函数——不同之处在于道具(titleimg 等)

    我们不是单独导入每个对象,而是使用import * 将它们组合在一起作为一个对象的属性。这允许 up 循环遍历它们。如果您决定将来添加或删除对象,它也会更加灵活,因为更改会自动应用。

    import * as projects from '../components/Data/projectsData';
    

    您的Projects 组件可以通过遍历所有可用项目来简化。我们在项目中使用Object.values(projects) 作为array 而不是键控对象,然后调用数组.map 函数。

    function Projects() {
      return (
        <>
          <Navbar1 />
          <div className="page">
            <div className="projects-container">
              {Object.values(projects).map((project) => (
                <ProjectImage
                  key={project.title} // items in a list need a unique key
                  {...project} // pass through all props of the project object
                />
              ))}
            </div>
          </div>
        </>
      );
    }
    

    我们可以创建一个ProjectDetails 组件,它可以检索当前 URL 的数据对象,然后使用这些属性。我们使用 react-router useParams hook 从 URL 中获取 "/:projectdetails"(也可以通过 props 完成)。

    export function ProjectDetails() {
      const { projectdetails } = useParams();
    
      // find the matching object from the array of projects
      // note that the data uses a `/` at the start, but the params does not
      const project = Object.values(projects).find(
        (project) =>
          project.link.toLowerCase().replace("/", "") === projectdetails.toLowerCase()
      );
    
      // need to handle any invalid urls
      if (!project) {
        // can use Redirect to redirect to a 404 page
        return <h1>Error: Project Not Found</h1>;
      }
    
      return (
        <div>
          <h1>{project.title} Details</h1>
          <ProjectImage {...project} />
        </div>
      );
    }
    

    CodeSandbox Link

    【讨论】:

    • 感谢您的回答。当我需要更多数据(如描述和更多照片)时,这仍然适用于 ProjectDetails 组件吗?我不会使用与 Projects 组件相同的数据文件,而是使用一个单独的文件,其中包含更多信息,包括描述和视频等。
    • 您将使用该方法来查找具有详细信息的对象。我在这里所做的替代方法——基于当前 URL 的内容——是在定义路由的地方循环遍历对象。对于每个项目,您将使用该 url 定义一个 Route,并且渲染函数将是一个箭头函数,将对象属性作为道具应用,即 render={() => }
    • 啊,我开始工作了,谢谢你的回答真的帮助我理解了事情并教会了我一些新的东西。这几天我一直在网上找,想弄明白。
    猜你喜欢
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 2021-06-30
    • 2019-05-30
    • 2022-01-21
    相关资源
    最近更新 更多