16

I am building a Netflix clone application, and I am using react-router-dom v5 to switch between different pages. However, when I click the Link tag in Navbar.jsx, the URL changes, but the corresponding component doesn't render. I have consulted numerous StackOverflow posts on this topic, however, I can't get it to work. Below is the code. Please help me, as I'm stuck on this for 3 days 😥.

What it should show, when navigating to /series from /: enter image description here

What it is actually showing: enter image description here

  1. index.js
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";

const container = document.getElementById("root");
const root = createRoot(container);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  1. App.jsx
import React from "react";

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import "./app.scss";
import Home from "./pages/home/Home";
import Watch from "./pages/watch/Watch";

const App = () => {
  return (
    <Router>
      <Switch>
        <Route exact path="/">
          <Home />
        </Route>
        <Route path="/movies">
          <Home type="movies" />
        </Route>
        <Route path="/series">
          <Home type="series" />
        </Route>
        <Route path="/watch">
          <Watch />
        </Route>
      </Switch>
    </Router>
  );
};

export default App;
  1. Home.jsx

import React from "react";
import Featured from "../../components/featured/Featured";
import Navbar from "../../components/navbar/Navbar";

import "./home.scss";

const Home = ({ type }) => {
  return (
    <div className="home">
      <Navbar />
      <Featured type={type} />
    </div>
  );
};

export default Home;
  1. Navbar.jsx

import React, { useState } from "react";

import "./navbar.scss";
import { Link } from "react-router-dom";

const Navbar = () => {
  const [isScrolled, setIsScrolled] = useState(false);

  window.onscroll = () => {
    setIsScrolled(window.scrollY === 0 ? false : true);
    return () => window.onscroll == null;
  };

  return (
    <div className={`navbar ${isScrolled ? "scrolled" : ""}`}>
      <div className="container">
          <img src="./netflix_logo.jpg"
            alt="netflix logo"
          />
          <Link to="/" className="link">
            <span>Home</span>
          </Link>
          <Link to="/series" className="link">
            <span>Series</span>
          </Link>
          <Link to="/movies" className="link">
            <span>Movies</span>
          </Link>
          <Link to="" className="link">
            <span>New and Popular</span>
          </Link>
          <Link to="" className="link">
            <span>My List</span>
          </Link>
      </div>
    </div>
  );
};

export default Navbar;
  1. Featured.jsx
import "./featured.scss";
import { IoMdPlay } from "react-icons/io";
import { FiInfo } from "react-icons/fi";

const Featured = ({ type }) => {
  return (
    <div className="featured">
      {type && (
        <div className="category">
          <span style={{ color: "white" }}>
            {type === "movies" ? "Movies" : "TV Series"}
          </span>
          <select name="genre" id="genre">
            <option>Genre</option>
            <option value="adventure">Adventure</option>
            <option value="comedy">Comedy</option>
            <option value="crime">Crime</option>
            <option value="fantasy">Fantasy</option>
            <option value="historical">Historical</option>
            <option value="horror">Horror</option>
            <option value="romance">Romance</option>
            <option value="sci-fi">Sci-fi</option>
            <option value="thriller">Thriller</option>
            <option value="western">Western</option>
            <option value="animation">Animation</option>
            <option value="drama">Drama</option>
            <option value="documentary">Documentary</option>
          </select>
        </div>
      )}
      <img
        src="https://m.media-amazon.com/images/M/MV5BNzM4OTkzMjcxOF5BMl5BanBnXkFtZTgwMTkxMjI1MTI@._V1_.jpg"
        alt="featured"
      />
      <div className="info">
        <img
          src="https://occ-0-1432-1433.1.nflxso.net/dnm/api/v6/LmEnxtiAuzezXBjYXPuDgfZ4zZQ/AAAABUZdeG1DrMstq-YKHZ-dA-cx2uQN_YbCYx7RABDk0y7F8ZK6nzgCz4bp5qJVgMizPbVpIvXrd4xMBQAuNe0xmuW2WjoeGMDn1cFO.webp?r=df1"
          alt=""
        />
        <span className="desc">
          When a beautiful stranger leads computer hacker Neo to a forbidding
          underworld, he discovers the shocking truth - the life he knows is the
          elaborate deception of an evil cyber-intelligence.
        </span>
        <div className="buttons">
          <button className="play">
            <IoMdPlay className="button-logo" />
            <span>Play</span>
          </button>
          <button className="more">
            <FiInfo className="button-logo" />
            <span>More Info</span>
          </button>
        </div>
      </div>
    </div>
  );
};

export default Featured;
2
  • Which specific routes are you having difficulty navigating to? By your inclusion of the Home and Navbar components am I correct in assuming you are having trouble navigating between the "/", "/movies" and "/series" paths? The Navbar doesn't link to anything else. Can you share the Featured component as well? Commented Apr 11, 2022 at 18:57
  • Hi @Drew, yes I'm having trouble switching from/to the "/", "/movies" and "/series" paths. I'll edit my question to include the Featured Component as well, however it doesn't use any react-router-dom functionality. Commented Apr 11, 2022 at 19:10

3 Answers 3

34

There's a compatibility issue between pre-5.3.3 versions of react-router-dom@5 and react@18.

Solutions

  1. Bugfix was merged into v5.3.3. Update to [email protected] or higher.

    From the project's root directory run:

  2. Revert back to React 17 (or React 17 syntax) and fix up the index.js file.

    import { StrictMode } from "react";
    import ReactDOM from "react-dom";
    
    import App from "./App";
    
    ReactDOM.render(
      <StrictMode>
        <App />
      </StrictMode>,
      document.getElementById("root")
    );
    
  3. Make the React.StrictMode component a child/descendent of the router component. Comment.

    Replace:

    <React.StrictMode>
      ...
      <BrowserRouter>
        ...
      </BrowserRouter>
    </React.StrictMode>
    

    with:

    <BrowserRouter>
      <React.StrictMode>
        ...
      </React.StrictMode>
    </BrowserRouter>
    
  4. Upgrade to react-router-dom@6 and fix up the routes.

    const App = () => {
      return (
        <Router>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/movies" element={<Home type="movies" />} />
            <Route path="/series" element={<Home type="series" />} />
            <Route path="/watch" element={<Watch />} />
          </Routes>
        </Router>
      );
    }
    
Sign up to request clarification or add additional context in comments.

4 Comments

Hi Drew, thank you so so much! I followed your 2nd solution (Upgrade to react-router-dom@6), refactored the code accordingly, and voila, it worked! None of my previous internet searches mentioned this incompatibility between react-router-dom@5 and react@18. Thanks to your reply, I am no longer stuck and will be able to proceed with the rest of the application.
This sorted my similar problem: stackoverflow.com/questions/72122588/…
Thanks so much, if I could vote this up 100 times I would
I have this exact issue with react-router-dom@6, and the methods that work are either by removing StrictMode or wrapping it inside the <RouterProvider>. Thank you for this answer, as it saved me a lot of days of debugging it.
1

First Solution and Best Solution:

  1. If you use are using React Router 5.3.x, check whether it is 5.3.3 in your package.json file.

  2. If it is not 5.3.3 uninstall the last version then install the bug-free version which has been resolved by John and updated in version 5.3.3.

Second Solution:

React has launched its StrictMode in its latest update. you can see it in an index.js file

index.js

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

So here your React Router is in the child component. And we have to make it a parent component.

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
  <React.StrictMode>
    <App />
  </React.StrictMode>
</BrowserRouter>
);

Third Solution:

Remove the Strict mode from the index.js file

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
    <App />
</BrowserRouter>
);

Comments

0

Updating to 5.3.3 solved the problem.

function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/home">Home</Link>
            </li>
            <li>
              <Link to="/login">Login</Link>
            </li>
          </ul>
        </nav>

        <Switch>
          <Route path="/login" component={Login} />
          <Route path="/home" component={Home} />
          <Route path="*" component={NoPage} />
        </Switch>
      </div>
    </Router>
  );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.