【问题标题】:React-router-dom nesting doesn't work in children componentsReact-router-dom 嵌套在子组件中不起作用
【发布时间】:2021-03-11 07:45:02
【问题描述】:

为了可视化和清晰的图片,我将首先显示应用程序的屏幕截图。

我正在使用 github api 来获取存储库和用户。简单的。现在 App.tsx 的外观是这样的;

// App.tsx
import React from "react";
import MainSearchPage from "./Components/MainSearchPage";
import Header from "./Components/Header";
import "./Sass/main.scss";

const App: React.FC = () => {
  return (
    <div className="App">
      <Header />
      <MainSearchPage />
    </div>
  );
};

export default App;

这是 MainSearchPage 组件;

// MainSearchPage.tsx
import React, { useContext } from "react";
import { GithubContext } from "../Context/GithubContext";
import searchPc from "../Icons/search-pc.svg";
import SearchResults from "./SearchResults";

const MainSearchPage: React.FC = () => {
  const { isSearched } = useContext(GithubContext);
  return (
    <div>
      {isSearched ? (
        <SearchResults />
      ) : (
        <div className="blank-search-page">
          <div className="blank-search-page__items">
            <img src={searchPc} alt="search-pc" />
            <p>Search results will appear here</p>
          </div>
        </div>
      )}
    </div>
  );
};

export default MainSearchPage;

当输入改变时,isSearch 变为真并且 SearchResults 正在呈现。这是问题开始的 SearchResults。

//SearchResults.tsx
import React from "react";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import MainSearchResults from "./MainSearchResults";
import SideBarSearchResults from "./SideBarSearchResults";
import UsersPage from "./UsersPage";

const SearchResults = () => {
  return (
    <div className="search-results">
      <Router>
        <SideBarSearchResults />
        <Switch>
          <Route path="/" component={MainSearchResults} />
          <Route path="/search-users" component={UsersPage} />
        </Switch>
      </Router>
    </div>
  );
};

export default SearchResults;

所以 MainSearchResults 基本上是右边的 repo 结果。我想侧边栏很明显。当我单击左侧的用户时,UsersPage 是应该呈现的组件。但是当我单击时没有任何反应。网址改变了,就是这样。控制台或任何东西都没有错误。在我设置“isSearched”状态之前它正在工作。但我认为这无关紧要。

侧边栏组件;

//SideBarSearchResults.tsx
import React, { useContext } from "react";
import repositoriesSVG from "../Icons/repositories.svg";
import usersSVG from "../Icons/users.svg";
import bookmarkblackSVG from "../Icons/bookmarkblack.svg";
import { Link } from "react-router-dom";
import { GithubContext } from "../Context/GithubContext";
const SideBarSearchResults: React.FC = () => {
  const { repoCount, userCount } = useContext(GithubContext);
  return (
    <div className="side-bar-search-results">
      <Link to="/">
        <div className="side-bar-search-results__repositories">
          <img src={repositoriesSVG} alt="repo" />
          <p className="result-title">Repositories</p>
          <p className="quantity">{repoCount ?? 0}</p>
        </div>
      </Link>
      <Link to="/search-users">
        <div className="side-bar-search-results__users">
          <img src={usersSVG} alt="users" />
          <p className="result-title">Users</p>
          <p className="quantity">{userCount ?? 0}</p>
        </div>
      </Link>
      <div className="side-bar-search-results__bookmarked ">
        <img src={bookmarkblackSVG} alt="bookmarked" />
        <Link to="/repo-details">
          <p className="result-title">Bookmarked</p>
        </Link>
        <p className="quantity">15</p>
      </div>
    </div>
  );
};

export default SideBarSearchResults;

【问题讨论】:

  • 控制台有错误吗?
  • 那么到底是什么问题?筑巢在哪里?或者更确切地说,您指的是什么具体的嵌套(如果有的话)?我看到 1 个路由器、交换机和路由。您的SideBarSearchResults 中的链接(??只是猜测)没有正确路由到UsersPage 中的嵌套路由的问题是什么?
  • 控制台没有错误,什么也没有出现。 url 改变了,就是这样。没有其他事情发生。抱歉,我可能应该将此添加到问题中。
  • 啊,我想我现在明白了,点击侧边栏中的“用户”应该路由到"/search-users" 路径,但这不起作用?您可以在问题中包含该侧边栏组件吗?
  • @DrewReese 我添加了,是的,网址发生了变化。但没有其他任何变化。如您所见,搜索结果填充用户页面。但我够不着。

标签: javascript reactjs react-router react-router-dom


【解决方案1】:

问题

Switch 组件匹配并呈现第一个匹配的路径,“/”是每个路径的前缀。换句话说,它总是首先匹配并返回的路径。

解决方案

重新排列您的Routes 以首先指定更具体的路径,然后按路径特异性的降序排列。

<Router>
  <SideBarSearchResults />
  <Switch>
    <Route path="/search-users" component={UsersPage} />
    <Route path="/" component={MainSearchResults} />
  </Switch>
</Router>

【讨论】:

  • 耶稣.. 我只是无语。实际上我花了 1 天的时间来切换订单......非常感谢你
  • 不是重新排序,而是让/ 路由精确解决问题?比如:
  • @Mateen 是的,这也可以解决这个问题,但是(IMO)添加 exact 属性只是为了强制匹配是不必要的,因为 Switch 最多只会返回一个匹配并且通过正确排序路线,您可以消除添加额外道具的需要。
  • 你是对的。但是注意订单是一项开销。不是吗?
  • @Mateen Overhead,是的,我想这涉及到一些开销。在这里搜索子路由以查找匹配路径是O(n) 操作,无论顺序如何,特别是考虑到除了在 JSX/DOM 中声明它们的方式之外没有设置顺序。开销都是一样的。
【解决方案2】:

作为对 Drew Reese 回答的补充:

当您使用任何路由匹配组件时,您需要知道它是如何工作的,以便您可以使用另一个库。 在react-router&lt;Router/&gt; 的情况下,默认情况下它不会独占渲染组件。这意味着,您的应用程序最终可能会为一个路由匹配两个路径并呈现第一个路径,因此 顺序确实很重要。 例如,如果您要路由'/products',它匹配//products那是你的情况。如何解决:

  • 使用exact 或,
  • 重新排序路线Drew Reese刚刚在他的回答中提到。

替代方案:

如果您不喜欢react-router? 的这种路径匹配怎么办? 这里有Reach Router,其路径匹配有点不同。到达路由器排名路径并呈现最有意义的路径。你可以阅读他们的path ranking。因此,您无需考虑顺序或使用额外的关键字exact,因为reach router 本身使用路径排名**系统 优先考虑路由器。

【讨论】:

  • 仅供参考,Router 组件以包含的方式呈现路由(所有匹配的路由/重定向/组件),Switch 更改此行为并仅呈现路由(第一个匹配的路由/重定向)。您描述的行为包含在react-router-dom v6 中,基本上 Reach Router 和 React Router 正在合并。在 react-router-dom v6 中,Switch 组件被替换为 Routes 组件并使用路径排名系统。 reacttraining.com/blog/react-router-v6-pre/#introducing-routes
猜你喜欢
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-07
  • 2018-07-31
  • 2020-06-02
  • 2022-08-17
  • 1970-01-01
相关资源
最近更新 更多