【问题标题】:useNavigate() may be used only in the context of a <Router> componentuseNavigate() 只能在 <Router> 组件的上下文中使用
【发布时间】:2021-12-27 04:50:03
【问题描述】:

我目前的代码是这样的,我正在尝试使用 react-router-dom 添加这个返回上一页的按钮,但我收到错误消息,提示“useNavigate() 只能在组件的上下文中使用。而且我网站上的所有组件都消失了。

function App() {
  const navigate = useNavigate();
  return (
    <BrowserRouter>
      <div>
      <button onClick={() => navigate(-1)}>go back</button>
        <Nav/>
        <Routes>
          <Route exact path="/" element={<Home/>}/>
          <Route exact path="/home" element={<Home/>}/>
          <Route exact path="/upcoming/:user" element={<Upcoming/>}/>
          <Route exact path="/record/:user" element={<Record/>}/>
          <Route path="*" element={<NotFound/>}/>
        </Routes>
      </div>
    </BrowserRouter>
  );
}

这是我在控制台中遇到的错误

【问题讨论】:

    标签: reactjs react-hooks react-router react-router-dom


    【解决方案1】:

    此错误引发useNavigateuseInRouterContext 将检查组件是否是 &lt;Router&gt; 的后代。

    下面是解释为什么不能在Router组件之外使用useNavigateuseLocation的源代码:

    useNavigate 底层使用useLocationuseLocation 将从LocationContext 获得location。如果要获取反应上下文,则应将组件呈现为上下文提供者的后代。 Router 组件使用LocationContext.ProviderNavigationContext.Provider。这就是为什么您需要将组件渲染为children,以便useNavigate 挂钩可以从NavigationContextLocationContext 提供程序获取上下文数据。

    你的环境是浏览器,所以你需要使用BrowserRouterBrowserRouter 是基于 Router 构建的。

    对此进行重构:

    App.jsx:

    function App() {
      const navigate = useNavigate();
      return (
          <div>
            <button onClick={() => navigate(-1)}>go back</button>
            <Nav/>
            <Routes>
              <Route exact path="/" element={<Home/>}/>
              <Route exact path="/home" element={<Home/>}/>
              <Route exact path="/upcoming/:user" element={<Upcoming/>}/>
              <Route exact path="/record/:user" element={<Record/>}/>
              <Route path="*" element={<NotFound/>}/>
            </Routes>
          </div>
      );
    }
    

    index.jsx:

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

    【讨论】:

      【解决方案2】:

      您在 BrowserRouter 提供程序之外使用钩子。这就是你收到错误的原因。像下面这样重构你的组件来解决这个问题

      function Root() {
        const navigate = useNavigate();
        return (
          <div>
            <button onClick={() => navigate(-1)}>go back</button>
            <Nav />
            <Routes>
              <Route exact path="/" element={<Home />} />
              <Route exact path="/home" element={<Home />} />
              <Route exact path="/upcoming/:user" element={<Upcoming />} />
              <Route exact path="/record/:user" element={<Record />} />
              <Route path="*" element={<NotFound />} />
            </Routes>
          </div>
        );
      }
      
      function App() {
        return (
          <BrowserRouter>
            <Root />
          </BrowserRouter>
        );
      }
      

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题,但测试了一个带有钩子 useNavigate 的组件。通过将我的组件包装在带有路由和浏览器路由器的路由中来解决它。希望这可以帮助其他有同样错误的人。

        let container = null;
            beforeEach(() => {
            container = document.createElement("div");
            document.body.appendChild(container);
        });
        
        afterEach(() => {
            // cleanup on exiting
            unmountComponentAtNode(container);
            container.remove();
            container = null;
        });
        
        test('finds qualified insurrance policies', () => {
            act(() => {
            render(
            <BrowserRouter>
                <Routes>   
                    <Route path="*" element= {<QuaifiedPolicies policyTypes={false} />}/>
                </Routes>
            </BrowserRouter>
                , container);
            });
            expect(screen.getByLabelText('some text'))
        });
        

        【讨论】:

        • 你不需要让它成为一个路由,只需用 BrowserRouter 包裹它就可以解决问题
        猜你喜欢
        • 2021-12-29
        • 2022-11-15
        • 1970-01-01
        • 2022-06-30
        • 2021-04-02
        • 2021-01-31
        • 1970-01-01
        • 2022-11-03
        相关资源
        最近更新 更多