将 window.location.pathname 和 window.location.hash 与导航栏一起使用时渲染组件出现问题

Problem with rendering component when using window.location.pathname and window.location.hash with navigation bar

我在尝试使用导航栏呈现 React 组件时遇到问题。我已经尝试了 Switch case 和 if-statement 的两种方法。

第一种方法是使用 window.location.hash,它可以工作并在单击时更改 url,但我必须刷新浏览器才能看到呈现正确的组件,即显示所选组件。

另一种方法是针对 window.location.pathname,它以所需的方式写入 url,但不是呈现所需的组件,而是呈现我的主页。

这里我会展示代码。

About.jsx(带Pathname的版本被注释掉了,用了if语句。两个都给我同样的问题):

import React from 'react';
import '../App.css';
import AboutMe from './About/AboutMe';
import AboutMeNavigationBar from './About/AboutMeNav';
import Career from './About/Career';
import Education from './About/Education';
import Skills from './About/Skills';

export default function About(){
    console.log(document.getElementsByClassName("about-nav-bar")[0]);
    return(
        <div>
            <AboutMeNavigationBar />
            {selectSection()}
        </div>
    );
}

function selectSection(){
    var path = window.location.pathname;
    var hash = window.location.hash;
    console.log(window.location);
    console.log(path);
    console.log(window.location.hash);
    switch (hash) {
        case '#skills':
            return <Skills />
        case '#career':
            return <Career />
        case '#education':
            return <Education />
        default:
            return <AboutMe />    
    }
    // if (path === "/about/skills") {
    //     console.log();
    //     return <Skills />
    // }
    // else if (path === "/about/career") {
    //     return <Career />
    // }
    // else if (path === "/about/education") {
    //     return <Education />
    // }
    // else return <AboutMe />
}

AboutMeNav.jsx(href=#....):

import React from 'react';
import '../../App';

export default function AboutNav(props){
    console.log(window.location.pathname);
    console.log(window.location.hash);
    return <Sections />
}

export function Sections(props){
    return(
            <ul className="about-nav-bar">
                <Section text="ABOUT ME" href="#aboutme"></Section>
                <Section text="SKILLS" href="#skills"></Section>
                <Section text="CAREER" href="#career"></Section>
                <Section text="EDUCATION" href="#education"></Section>
            </ul>
    );
}

export function Section(props){
    return(
        <li>
            <a href={props.href}>{props.text}</a>
        </li>
    );
}

AboutMeNav.jsx(href="/about/aboutme" 等):

......
.........
export function Sections(props){
    return(
            <ul className="about-nav-bar">
                <Section text="ABOUT ME" href="/about/aboutme"></Section>
                <Section text="SKILLS" href="/about/skills"></Section>
                <Section text="CAREER" href="/about/career"></Section>
                <Section text="EDUCATION" href="/about/education"></Section>
            </ul>
    );
}
......
..........

来到第二个场景,它在浏览器中显示正确的 url,但一直将我重定向到主页。 将显示主要 App.js 代码,因为它奇怪地根据该开关案例重定向:

import './App.css';
import NavigationBar from './Components/Navigationbar';
import Home from './Components/Home';
import About from './Components/About';
import Contact from './Components/Contact';

function App() {
  function switchPage(){
    switch (window.location.pathname) {
      case '/about':
        return( <About />);
      case '/contact':
        return( <Contact />);
      default:
        return(<Home />);
    }
  }

  return (
    <div className="App">
      <NavigationBar className="Navbar" /> 
      
      <header className="App-header">
          {switchPage()}
      </header>
    </div>
  );
}

export default App;

这是我的页面最初的样子:

我的文件结构

有人可以帮我解决这些问题吗?有没有不使用 react-router 的解决方案?

感谢所有帮助。非常感谢。

因为更改 URL 不会触发重新呈现应用程序。所以你需要监听 URL 变化事件来更新你的组件。我不知道要为路径名监听哪个事件。但是对于哈希,你可以尝试 hashchange.

哈希示例:

export default function App() {
  const [hash, setHash] = React.useState(window.location.hash);
  React.useEffect(() => {
    const handler = () => {
      setHash((prev) => {
        const newHash = window.location.hash;
        if (prev !== newHash) {
          return newHash;
        }
        return prev;
      });
    };
    window.addEventListener("hashchange", handler);
    return () => {
      window.removeEventListener("hashchange", handler);
    };
  }, []);
  return (
    <div className="App">
      <nav>
        <ul>
          <li>
            <a href="#hash1">hash 1</a>
          </li>
          <li>
            <a href="#hash2">hash 2</a>
          </li>
        </ul>
      </nav>
      <div>Current hash: {hash}</div>
    </div>
  );
}

使用 SwitchRoute: https://reactrouter.com/web/api/Switch,您不必使用自己的 switch case ;)