BrowserRouter 内的链接标记仅更改 URL,但不渲染组件

问题描述 投票:0回答:3

我正在构建一个 Netflix 克隆应用程序,我正在使用

react-router-dom v5
在不同页面之间切换。但是,当我单击
Link
中的
Navbar.jsx
标签时,URL 会发生变化,但相应的组件不会呈现。我已经查阅了许多关于这个主题的StackOverflow帖子,但是,我无法让它工作。下面是代码。请帮助我,因为我已经被这个问题困扰了 3 天了😥。

/series
导航到
/
时应显示什么: enter image description here

它实际显示的内容: 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. 精选.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;
javascript reactjs react-router-dom netflix
3个回答
32
投票

5.3.3 之前版本的

react-router-dom@5
react@18
之间存在兼容性问题。

解决方案

  1. 错误修复已合并到 v5.3.3 中。更新至

    [email protected]
    或更高版本。

    从项目的根目录运行:

    Edit link-tag-inside-browserrouter-changes-only-the-url-but-doesnt-render-the-compo (forked)

  2. 恢复到 React 17(或 React 17 语法)并修复

    index.js
    文件。

    import { StrictMode } from "react";
    import ReactDOM from "react-dom";
    
    import App from "./App";
    
    ReactDOM.render(
      <StrictMode>
        <App />
      </StrictMode>,
      document.getElementById("root")
    );
    

    Edit link-tag-inside-browserrouter-changes-only-the-url-but-doesnt-render-the-compo

  3. 使

    React.StrictMode
    组件成为路由器组件的子组件/后代组件。 评论

    更换:

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

    与:

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

    Edit link-tag-inside-browserrouter-changes-only-the-url-but-doesnt-render-the-compo (forked)

  4. 升级到

    react-router-dom@6
    并修复路线。

    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>
      );
    }
    

    Edit link-tag-inside-browserrouter-changes-only-the-url-but-doesnt-render-the-compo (forked)


1
投票

第一个解决方案和最佳解决方案:

  1. 如果您使用的是 React Router 5.3.x,请检查您的 package.json 文件中是否为 5.3.3。

  2. 如果不是 5.3.3,请卸载最后一个版本,然后安装已被 John 解决并在 5.3.3 版本中更新的无错误版本。

第二种解决方案:

React 在最新更新中推出了 StrictMode。 你可以在index.js文件中看到它

index.js

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

所以这里你的 React Router 位于子组件中。我们必须将其设为父组件。

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

第三种解决方案:

从index.js文件中删除严格模式

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

0
投票

更新到5.3.3解决了问题。

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>
  );
© www.soinside.com 2019 - 2024. All rights reserved.