使用 react-router-v6 触发 Link 挂钩时出错

Error triggering a Link hook using react-router-v6

我正在将源代码从 react-router-5 更新到版本 6。到目前为止我收到此错误:

Error: [div] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>

当我激活此组件中的 link(QuoteItem.js) 时触发错误:

const QuoteItem = (props) => { 
  return (
    <li className={classes.item}>
      <figure>
        <blockquote>
          <p>{props.text}</p>
        </blockquote>
        <figcaption>{props.author}</figcaption>
      </figure>
      <div className={classes.item}>
          <Link className='btn' to={`/quotes/${props.id}`}>View Fullscreen</Link>
        </div>
    </li>
  );
};

在另一个组件 (VerQuotes) 中我定义了路由:

const VerQuotes = () => {
  return (
    <div>
      <main>
        <Layout>
          <Routes>
            <Route path="quotes" element={<AllQuotes />} />

            <Route path="new-quote" element={<NewQuote />} />

            <Route path="quotes/:quoteId" element={<QuoteDetail />} />
          </Routes>
        </Layout>
      </main>
    </div>
  );
};

我有点不知道如何解决这个错误,非常感谢您的意见。

非常感谢

更新

报价详情

const QuoteDetail = () => {
  const match = useNavigate();
  const params = useParams();
  const { quoteId } = params;


  const { sendRequest, status, data: loadedQuote, error } = useHttp(getSingleQuote, true);

  //const quote = DUMMY_NOTES.find((quote) => quote.id === params.quoteId);
  useEffect(() => {
    sendRequest(quoteId);
  }, [sendRequest, quoteId]);

  if(status === "pending"){
    return (
      <div className="centered">
        <LoadingSpinner />
      </div>
    );
  }

  if(error){
    return <p className="centered">{error}</p>;
  }

  if (!loadedQuote.text) {
    return <p>No Quote Found!</p>;
  }
  return (
    <Fragment>
      <HighlightedQuote text={loadedQuote.text} author={loadedQuote.author} />
      <Routes>
      <Route path={match}>
        <div className="centered">
          <Link
            className="btn--flat"
            to={`${match}/comments`}
          >
            Load Comments
          </Link>
        </div>
      </Route>
      <Route path={`${match}/comments`} element={<Comments />}></Route>
      </Routes>
    </Fragment>
  );
};

问题

跟踪您的代码后,我发现您在 QuoteDetail 组件中有几个问题。

  1. 您使用了 const match = useNavigate();所以 match 实际上是 navigate 函数)但后来使用 match 尝试为 Route.
  2. 形成一个 path 字符串
  3. Route 组件的 children 属性仅用于渲染嵌套路由。您看到的错误是使用了不是 Route 组件的 div 元素。

代码

<Routes>
  <Route path={match}>
    <div className="centered">
      <Link
        className="btn--flat"
        to={`${match}/comments`}
      >
        Load Comments
      </Link>
    </div>
  </Route>
  <Route path={`${match}/comments`} element={<Comments />}></Route>
</Routes>

解决方案

删除 const match = useNavigate(); 因为它没有被使用,并且将 div 放入 Routeelement 属性中。更改 path 道具以使用已建立的当前路由路径的相对路由。

const QuoteDetail = () => {
  const params = useParams();
  const { quoteId } = params;

  const { sendRequest, status, data: loadedQuote, error } = useHttp(
    getSingleQuote,
    true
  );

  //const quote = DUMMY_NOTES.find((quote) => quote.id === params.quoteId);
  useEffect(() => {
    sendRequest(quoteId);
  }, [sendRequest, quoteId]);

  if (status === "pending") {
    return (
      <div className="centered">
        <LoadingSpinner />
      </div>
    );
  }

  if (error) {
    return <p className="centered">{error}</p>;
  }

  if (!loadedQuote.text) {
    return <p>No Quote Found!</p>;
  }
  return (
    <Fragment>
      <HighlightedQuote text={loadedQuote.text} author={loadedQuote.author} />
      <Routes>
        <Route
          path="/"
          element={
            <div className="centered">
              <Link className="btn--flat" to="comments">
                Load Comments
              </Link>
            </div>
          }
        />
        <Route path="comments" element={<Comments />} />
      </Routes>
    </Fragment>
  );
};