错误:useHref() 只能在 <Router> 组件的上下文中使用。当我直接将 url 设置为 localhost:3000/experiences 时它会起作用

ten*_*tis 94 reactjs react-router react-router-dom

我有一个导航栏,当路线单击时发生变化时,它会在每条路线中呈现。

./components/navbar.jsx

import React, { Component } from 'react';
import '../App.css';
import { Link } from 'react-router-dom';



class Navbar extends Component {
    constructor(props) {
        super(props);
        this.state = {};
    }
    render() {
        return (
            <div id = 'navbar'>

                <div className='name-head'>
                    My Name
                </div>
            
            
                <div id = 'nav-links-container'>
                    
                    <Link to='/experiences'>
                        <div className = 'nav-links'>
                            Experiences
                        </div>
                    </Link>

                    <div className = 'nav-links'>
                        Projects
                    </div>

                    <div className = 'nav-links'>
                        Skills
                    </div>

                    <div className = 'nav-links'>
                        Resume
                    </div>

                </div>
                
            </div>
        );
    }
}

export default Navbar;
Run Code Online (Sandbox Code Playgroud)

./components/experiences.jsx

import React, { Component } from 'react';


class Experiences extends Component {
    
    render() { 
        return (
            <div>
                <h1>hi</h1>
            </div>
        );
    }
}
 
export default Experiences;
Run Code Online (Sandbox Code Playgroud)

索引.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import Navbar from './components/Navbar';
import Home from './components/Home';
import Experiences from './components/experience';

import {
  BrowserRouter as Router, 
  Routes, 
  Route
} from 'react-router-dom';



ReactDOM.render(

  <React.StrictMode>

    <Navbar />

    <Router>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/experiences" element={<Experiences />} />
      </Routes>

    </Router>

  </React.StrictMode>,

  document.getElementById('root')
);


reportWebVitals();
Run Code Online (Sandbox Code Playgroud)

<Link>当我从导航栏中的体验标签中删除 时,不会出现错误。这里发布了一个类似的问题:错误:useHref() 只能在 <Router> 组件的上下文中使用 ,但没有帮助。

我正在使用反应路由器 v6

Dre*_*ese 164

问题

您正在路由上下文之外渲染导航栏。它Router不知道链接正在尝试链接到它正在管理的哪些路由。直接导航时路由起作用的原因"/experiences"Router应用程序安装时知道 URL。

<Navbar /> // <-- outside router!!

<Router>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/experiences" element={<Experiences />} />
  </Routes>
</Router>
Run Code Online (Sandbox Code Playgroud)

解决方案

将其移至路由上下文Router,以便感知并可以正确管理路由。

<Router>
  <Navbar />
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/experiences" element={<Experiences />} />
  </Routes>
</Router>
Run Code Online (Sandbox Code Playgroud)

react-router-dom@6.4数据API

如果您使用新的数据路由器,并且尝试在组件外部渲染标题/导航栏,则可能会遇到此问题RouterProvider。为此,您可以创建一个布局路由,该布局路由是传递给createBrowserRouter和其他变体)的路由配置的一部分。

例子:

const AppLayout = () => (
  <>
    <Navbar />
    <Outlet />
  </>
);

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route element={<AppLayout />}>
      <Route path="/" element={<Home />} />
      <Route path="/experiences" element={<Experiences />} />
    </Route>
  )
);
Run Code Online (Sandbox Code Playgroud)

...

<RouterProvider router={router} />
Run Code Online (Sandbox Code Playgroud)


Ale*_*tro 34

在 React Route v6 中,您可以使用 < BrowserRouter >为整个应用程序提供路由上下文来解决此问题

这是index.js的完整示例

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { App }  from './components/App/App.jsx';


ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>  //that is the key
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)

  • @Cat-Lord 和 Ale,它不是特定于 v6 的,始终存在在任何路由上下文之外渲染链接和路由的问题。只是 v6 是第一个使用失败不变检查来抛出错误的主要版本。以前不会出现任何错误,您会被困在那里,想知道为什么没有任何效果。正如您所看到的,即使出现错误,有些人仍然不知道该怎么做。 (2认同)

小智 17

如果您仍然遇到这个问题,那是因为react-router-dom当您尝试对其进行单元测试时,依赖于 React 上下文来工作。这使得<Link /><Route />过时。
尝试阅读react-router-dom文档

而不是使用

render(<Example />)
Run Code Online (Sandbox Code Playgroud)

里面有 或 ,你可以尝试

render(<MemoryRouter>
    <Example />
</MemoryRouter>)
Run Code Online (Sandbox Code Playgroud)

希望这能解决您的问题


KAR*_*N.A 9

react-router-dom:6.xreact:18.x中,我们应该通过以下方式使用Router来解决该问题:

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { App }  from './App.js';

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

root.render(
  <React.StrictMode>
    <Router>  // Router
      <App /> // Application
    </Router>
  </React.StrictMode>
); 
Run Code Online (Sandbox Code Playgroud)


小智 7

链接位于导航栏内部且导航栏位于路由器外部=> 链接位于路由器外部=> 路由器不会管理链接

解决方案

将导航栏移至路由器部分。例子:

<Router>
  <Navbar /> // <===========
  <Routes>
    <Route />
    <Route />
  </Routes>
</Router>
Run Code Online (Sandbox Code Playgroud)