React-router-dom nesting doesn’t work in children components

For visualisation and clear picture, I will show the app’s screen shot first.

enter image description here

I’m using github api to fetch Repos and Users. Simple. Now this how App.tsx looks;

// 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;

This is the MainSearchPage component;

// 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;

When input changes, isSearch becomes true and SearchResults is rendering. This is the SearchResults, where the problem begins.

//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;

So MainSearchResults is basically repo results on the right. Sidebar is obvious I suppose. And UsersPage is the component that should be rendered when I click the Users on the left. But nothing happens when I click. Url changes and that’s it. No errors in the console or anything. It was working before I put “isSearched” state. But I don’t think it should matter.

SideBar component;

//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;

Answer

Issue

The Switch component matches and renders the first matched path, and “/” is a prefix for every path. In other words, it will always be the path matched and returned first.

Solution

Reorder your Routes to specify the more specific paths first, and go in descending order of path specificity.

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

Leave a Reply

Your email address will not be published. Required fields are marked *