React Route: 使用嵌套路由加载评论以及 useRouteMatch 钩子函数

时间:2025-02-07 20:50:20

使用嵌套路由,Link 的 to 属性使用实际值,Comment 的 Route 定义则使用占位符。

在定义的 Route 内,可以 呈现任意JSX代码,所以下面这样的代码是合法的:

  <Route path={`/quotes/${params.quoteId}`} exact>
    <div className="centered">
      <Link className="btn--flat" to={`/quotes/${params.quoteId}/comments`}>
        Load Comments
      </Link>
    </div>
  </Route>

comments 没有加载时,显示链接 button,加载 comments 后,因为路由不匹配,button 消失, button 的 Route 具有 exact 属性。

使用 useRouteMatch 钩子函数的目的是,使代码更灵活,避免 里路由修改后,例如如果将 /quotes 改成 /quote,其他页面里因为路由写死了,到处需要进行同步调整。

import { Fragment } from "react";
import { useParams, Route, Link, useRouteMatch } from "react-router-dom";
import Comments from "./../components/comments/Comments";
import HighlightedQuote from "./../components/quotes/HighlightedQuote";

const DUMMY_QUOTES = [
  { id: "q1", author: "Max", text: "Learning React is fun!" },
  { id: "q2", author: "Max", text: "Learning React is great!" },
];

const QuoteDetail = () => {
  const match = useRouteMatch();
  const params = useParams();

  const quote = DUMMY_QUOTES.find((quote) => quote.id === params.quoteId);
  if (!quote) {
    return <p>No quote found!</p>;
  }

  return (
    <Fragment>
      <HighlightedQuote text={quote.text} author={quote.author} />
      <Route path={match.path} exact>
        <div className="centered">
          <Link className="btn--flat" to={`${match.url}/comments`}>
            Load Comments
          </Link>
        </div>
      </Route>
      <Route path={`${match.path}/comments`}>
        <Comments />
      </Route>
    </Fragment>
  );
};

export default QuoteDetail;