Nav Link not rerendering page when clicked. Force update freezes page.

huangapple go评论62阅读模式
英文:

Nav Link not rerendering page when clicked. Force update freezes page

问题

我正在构建的网站上有一个导航栏。导航栏中的链接指向页面中的一个部分(#id),但不会跳转到该部分,只会更新网址。如果我在地址栏中键入网址,它能正常工作,但当使用链接时却没有任何反应。

只有在我强制页面重新渲染时才起作用,但在重新渲染后,页面会冻结,并且控制台会报错:Uncaught TypeError: Cannot read properties of undefined (reading 'forceUpdate')。我尝试过在onClick事件中使用setState来强制重新渲染,也尝试过使用withRouterNavBar组件上。

我阅读过如果必须强制页面渲染,那么可能我做错了什么,但我刚开始学习React,过去几天一直在寻找更好的解决方法,但仍然找不到更好的方法。

英文:

I have a nav bar for a website I'm building. The links in the nav bar to a section (#id) in the page but do not go to the section and only update the url. If I type in the url in the address bar, it works correctly but when using the link nothing happens.

It only works if I force the page to rerender, but after rerendering the page freezes and I get an error in the console: Uncaught TypeError: Cannot read properties of undefined (reading 'forceUpdate'). I added an onClick and also tried using setState to force re-render.

Index.js

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

App.js

function App() {
  return (
    <div>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/home" element={<Home />} />
      </Routes>
    </div>
  );
}

export default App;

Home.jsx

function Home() {
  return (
    <div>
      <Container fluid>
        <NavBar />
        <HomeContent />
      </Container>
      <Pricing />
      <Footer />
    </div>
  );
}

export default Home;

NavBar.jsx

function handleClick() {
  this.setState({ state: this.state });
  // this.forceUpdate();
}

function NavBar() {
  return (
    <>
      <Navbar variant="dark" expand="lg">
        <Container>
          <Navbar.Brand onClick={handleClick} as={Link} to="/home">
          </Navbar.Brand>
          <Navbar.Toggle aria-controls="basic-navbar-nav" />
          <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="justify-content-end flex-grow-1 pe-3">
              <Nav.Link onClick={handleClick} as={Link} to="/home">
                Home
              </Nav.Link>
              <Nav.Link onClick={handleClick} as={Link} to="/home#pricing">
                Pricing
              </Nav.Link>
            </Nav>
          </Navbar.Collapse>
        </Container>
      </Navbar>
    </>
  );
}

export default NavBar;

Pricing.jsx

function Pricing() {
  return (
    <section id="pricing">
      <h2 className="section-heading">This is the pricing section</h2>
    </section>
  );
}

export default Pricing;

I also tried using withRouter on the NavBar component

I read that if I have to resort to forcing the page to render then I may be doing something wrong but I'm new to React and I've been searching for the past couple of days on better ways to do this but still couldn't find a better way to do it.

答案1

得分: 2

this.setStatethis.forceUpdate 是较旧的 React 基于类的组件方法。它们在 React 函数组件中不起作用。

react-router-dom 单独不处理哈希链接,即导航到特定路由路径 然后 滚动到特定哈希锚点。目前 react-router-hash-link 仍然与 react-router-dom@6 配合使用。从 react-router-hash-link 中导入 HashLink 并用它替代 RRD 中的 Link 组件。

示例:

import React from "react";
import { Nav, Navbar } from "react-bootstrap";
import { Link } from "react-router-dom";
import { HashLink } from "react-router-hash-link"; // <-- 导入哈希链接

function NavBar() {
  return (
    <Navbar bg="dark" variant="dark" expand="lg">
      <Navbar.Brand as={Link} to="/home"></Navbar.Brand>
      <Navbar.Toggle aria-controls="basic-navbar-nav" />
      <Navbar.Collapse id="basic-navbar-nav">
        <Nav className="justify-content-end flex-grow-1 pe-3">
          <Nav.Link as={Link} to="/home">
            Home
          </Nav.Link>
          <Nav.Link as={HashLink} to="/home#pricing"> // <-- 哈希链接
            Pricing
          </Nav.Link>
          <Nav.Link as={HashLink} to="/home#about">   // <-- 哈希链接
            About
          </Nav.Link>
          <Nav.Link as={HashLink} to="/home#contact"> // <-- 哈希链接
            Contact
          </Nav.Link>
        </Nav>
      </Navbar.Collapse>
    </Navbar>
  );
}

export default NavBar;

Nav Link not rerendering page when clicked. Force update freezes page.

英文:

this.setState and this.forceUpdate are older React class-based-only component methods. They won't work in React function components.

react-router-dom alone doesn't deal/handle with hash links, i.e. navigating to a specific route path and then scrolling to a specific hash anchor. Currently the react-router-hash-link still works with react-router-dom@6. Import the HashLink from react-router-hash-link and use instead of the Link component from RRD.

Example:

import React from "react";
import { Nav, Navbar } from "react-bootstrap";
import { Link } from "react-router-dom";
import { HashLink } from "react-router-hash-link"; // <-- import hash link

function NavBar() {
  return (
    <Navbar bg="dark" variant="dark" expand="lg">
      <Navbar.Brand as={Link} to="/home"></Navbar.Brand>
      <Navbar.Toggle aria-controls="basic-navbar-nav" />
      <Navbar.Collapse id="basic-navbar-nav">
        <Nav className="justify-content-end flex-grow-1 pe-3">
          <Nav.Link as={Link} to="/home">
            Home
          </Nav.Link>
          <Nav.Link as={HashLink} to="/home#pricing"> // <-- hash link
            Pricing
          </Nav.Link>
          <Nav.Link as={HashLink} to="/home#about">   // <-- hash link
            About
          </Nav.Link>
          <Nav.Link as={HashLink} to="/home#contact"> // <-- hash link
            Contact
          </Nav.Link>
        </Nav>
      </Navbar.Collapse>
    </Navbar>
  );
}

export default NavBar;

Nav Link not rerendering page when clicked. Force update freezes page.

答案2

得分: -1

解决问题的最佳方法是在您的 Web 应用程序中创建 React 路由器结构。我建议您阅读 React 路由器的入门页面

此外,在您的情况下,我建议您创建以下结构的 React 路由器结构:

您将有一个主 index.js 文件:

const router = createBrowserRouter([
    {
        path: "/",
        element: <Layout />,
        children: [
            {
                path: "mainpage/",
                element: <MainPage />,
            },
        ],
    },
]);

您将没有 app.js 文件。您只会有一个 layout.jsx 文件:

import { Outlet } from 'react-router-dom';
import Nav from "./components/Nav";

const Layout = () => {
    return (<>
        <Nav />
        <Outlet />
    </>)
}

您只需在 index.js 中添加路径和更多子项。只需创建一些组件并将它们添加到 children 数组中作为主页面。

在您的导航组件中,您必须像以下导航组件示例中那样有链接到您的页面:

import React from 'react';
import { Link } from "react-router-dom";

function Nav(props) {
  return (
    <header className="header">
      <div className="header-container">
        <nav className="header-nav">
          <ul className="nav-list">
            <li>
              <Link to={`mainpage/`}>Home</Link>
            </li>
            <li>
              <Link to={`News/`}>News</Link>
            </li>
            <li>
              <Link to={`About/`}>About</Link>
            </li>
            <li>
              <Link to={`Contacts`}>Contacts</Link>
            </li>
          </ul>
        </nav>
      </div>
    </header>
  );
}

export default Nav;

希望这能解决您的问题。

英文:

The best way to solve your problem to create React router structure in your web app. I suggest you to go through React router beginners page.

Also, in your case I suggest to create React router structure such as this structure:

You will have the main index.js file:


const router = createBrowserRouter([
{
path: &quot;/&quot;,
element: &lt;Layout /&gt;,
children: [
{
path: &quot;mainpage/&quot;,
element: &lt;MainPage /&gt;,
},
],
},
]);

You will not have app.js file. You will just have a layout.jsx file:


import { Outlet } from &#39;react-router-dom&#39;;
import Nav from &quot;./components/Nav&quot;;
const Layout = () =&gt; {
return (&lt;&gt;
&lt;Nav /&gt;
&lt;Outlet /&gt;
&lt;/&gt;)
}

And you should just add paths and more children to index js. Just create some components and add them to children array as a main page one.

And in your nav component you must have links to your pages like in the following nav component example:


import React from &#39;react&#39;;
import { Link } from &quot;react-router-dom&quot;;
function Nav(props) {
return (
&lt;header className=&quot;header&quot;&gt;
&lt;div className=&quot;header-container&quot;&gt;
&lt;nav className=&quot;header-nav&quot;&gt;
&lt;ul className=&quot;nav-list&quot;&gt;
&lt;li&gt;
&lt;Link to={`mainpage/`}&gt;Home&lt;/Link&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;Link to={`News/`}&gt;News&lt;/Link&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;Link to={`About/`}&gt;About&lt;/Link&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;Link to={`Contacts`}&gt;Contacts&lt;/Link&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;/div&gt;
&lt;/header&gt;
);
}
export default Nav;

I hope you will solve your issue.

huangapple
  • 本文由 发表于 2023年2月18日 03:47:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75488649.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定