首页 > 解决方案 > 在 react-routing 上渲染一个新页面,但它会在当前页面内渲染它

问题描述

这将显示一个卡片组件,如果用户单击<Link>read</Link>它应该重新呈现一个新页面,用户会看到该组件。

import React from "react";
import { Button } from "react-bootstrap";
import "./CardComponent.css";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Content from "./ContentFolder/Content";

function CardComponent(props) {
  return (
    <Router>
      <div class="card">
        <div className="uppercard">
          <img
            className="bookCover"
            src={props.img}
            alt=""
            width="120px"
            height="150px"
          />
          <h3>{props.title}</h3>

          <h6>By{props.author}</h6>
        </div>
        <div className="lowerCard">{props.points}</div>
        <Link to={"/" + props.title + props.author}>Read</Link>
      </div>
      <Switch>
        <Route
          exact
          path={`/${props.title+props.author}`}
          component={Content}
        >
          <Content title={props.title} author={props.author}
            points={props.points}
          />
          
        </Route>
      </Switch>
    </Router>
  );
}

export default CardComponent;

单击读取时,我想在不同的页面上呈现此内容组件。

总之,目标是当用户单击其中一个卡片组件时,在新页面上显示所有信息。

import React from "react";
import Mynavbar from "../Partials/Mynavbar";
import MyFooter from "../Partials/Footer";
import { Container } from "react-bootstrap";
import "./Content.css";

function Content(props) {
  return (
    <div>
      <Mynavbar />
      <Container className="main">
        <h4>{props.title}</h4>
        <h6>By {props.author}</h6>
         <ul>
          {props.points.map((point, i) => {
            return <li>{point}</li>;
          })}
        </ul> 
      </Container>
      <MyFooter />
    </div>
  );
}
export default Content;



标签: reactjsreact-routerreact-router-dom

解决方案


问题:Router内部CardComponent

需要存在Router于. App内部Router和外部的所有Switch内容都将呈现在每个页面上。所以现在你的卡代码甚至会出现在Content路线上。我们希望 theCard和 theContent分开Route

问题:不明确的 URL 结构

需要你的网址看起来像"/${props.title+props.author}"吗?这是一个非常糟糕的结构,因为您不可能从 URL 向后工作到内容。内容是"/Harry PotterJ.K. Rowling"什么?哪一部分是标题,哪一部分是作者?没有分隔符所以你不知道。您必须遍历所有书籍的列表,加入它们的标题和作者并将其与您的字符串进行比较。

典型的 URL 将基于id, like "/book/5"。我在这里没有看到任何关于 id 的提及,所以我们可以使用title.

解决方案

应用程序路由可能如下所示:

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/book/:title" component={BookDetails}/>
        <Route path="/" component={BookList}/>
      </Switch>
    </Router>
  )
}

让我们摆脱所有的路由,CardComponent让它只显示一本书的卡片,其中包含指向书籍详细信息的链接。

function CardComponent(props: Book) {
  return (
    <div className="card">
      <div className="uppercard">
        <img
          className="bookCover"
          src={props.img}
          alt=""
          width="120px"
          height="150px"
        />
        <h3>{props.title}</h3>

        <h6>By{props.author}</h6>
      </div>
      <div className="lowerCard">{props.points}</div>
      <Link to={"/book/" + props.title}>Read</Link>
    </div>
  );
}

我们的主页可能会显示这些卡片的列表。

function BookList() {
  // get books from somewhere -- a database? a json file?
  const books = ???;

  return (
    <ul className="bookList">
      {books.map((book) => (
        <CardComponent {...book} key={book.title} />
      ))}
    </ul>
  );
}

BookDetails是一个单独的路由,所以我们需要从 URL 中获取 book。

function BookDetails(props: RouteComponentProps) {
  // get the title from the URL
  // is automatically encoded and needs to be decoded
  const title = decodeURIComponent(props.match.params.title);
  // find the book object from your data source
  const book = ???
  // from a JSON array: BOOKS.find(book => book.title.toLowerCase() === title.toLowerCase() );

  // redirect to error page if no matching book
  if ( ! book ) {
    return <Redirect to="/404" />
  }

  // can render your Content component, but only after we get the book
  return (
    <Content {...book} />
  )
}

推荐阅读