3

This is not duplicate of this because the answers there don't address how to do this with router 6.4 (namely with createBrowserRouter and createRoutesFromElements). Also not sure if component layout is similar.


This is my code:

const router = createBrowserRouter(
  createRoutesFromElements(
    <React.Fragment>
      <Route path="/" element={<Test />} />
      <Route path="dashboard" element={<Test2 />} />
    </React.Fragment>
  )
);

const { Header, Content, Sider } = Layout;
function App() {
  return (
    <Layout style={{ height: "100%" }}>
      <Header className="header">
        <Menu theme="dark" mode="horizontal" defaultSelectedKeys={["2"]} items={items1} />
      </Header>
      <Layout>
        <Content
          style={{
            padding: 24,
            margin: 0,
            minHeight: 280,
          }}
        >
          <RouterProvider router={router} />
        </Content>
      </Layout>
    </Layout>
  );
}

I am getting error

useHref() may be used only in the context of a component

I understand this is related to my Links not embedded within Router, but using this new API of 6.4 react router how do I solve this problem?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • I specifically mentioned that my question wasn't duplicate and explained the reasons and it still got closed? –  Oct 28 '22 at 08:43
  • It's the same issue. The `Link` component still needs to be rendered within a routing context provided by a router. RRDv6.4 didn't change how the routing context works. – Drew Reese Oct 28 '22 at 08:44
  • @DrewReese I don't know how to create that routing context because I am **using the new API** that's the problem. So how do I create that routing context in my example? –  Oct 28 '22 at 08:45
  • You created it with ``. You are passing the router there. The links need to be used inside the router. – Drew Reese Oct 28 '22 at 08:46
  • @DrewReese Well but you can see I have rendered that inside the `Content` component because the routes must be drawn there, and the links in the Header. Do you see the problem? What can I do in such situation? –  Oct 28 '22 at 08:47

1 Answers1

1

Even with the new RRDv6.4 Data APIs and Data Routers, the Link components still need to be rendered within the routing context. You can move all the App component layout to be a layout route configured when you create the router.

Example:

const { Header, Content, Sider } = Layout;

const AppLayout = () => (
  <Layout style={{ height: "100%" }}>
    <Header className="header">
      <Menu
        theme="dark"
        mode="horizontal"
        defaultSelectedKeys={["2"]}
        items={items1}
      />
    </Header>
    <Layout>
      <Content
        style={{
          padding: 24,
          margin: 0,
          minHeight: 280,
        }}
      >
        <Outlet />
      </Content>
    </Layout>
  </Layout>
);

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route element={<AppLayout />}>
      <Route path="/" element={<Test />} />
      <Route path="dashboard" element={<Test2 />} />
    </Route>
  )
);

...

function App() {
  return (
    <RouterProvider router={router} />
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Thanks I will look into this, I suggest you also update this answer: https://stackoverflow.com/a/70220520/20356518 –  Oct 28 '22 at 08:53
  • @john I could do that, it's the same underlying issue, but it's caused by different scenarios. – Drew Reese Oct 28 '22 at 08:59
  • One more thing, is this correct: `}> } /> ` I want slightly different layout. When user goes to '/', by default I want to show `Test2` inside App. Sorry for format will try to fix it –  Oct 28 '22 at 09:01
  • @john I just used the two routes from your example, but no, you can't have two routes rendering on the same path. Oh, wait, the `App` is a parent route. Yeah, you can do the routes like that. – Drew Reese Oct 28 '22 at 09:04
  • Yeah it is parent but what is confusing me is that I used **same path** on parent and child is this accepted in such situations? –  Oct 28 '22 at 09:13
  • @john Yeah, it's fine. You may also see *that* child route path that matches the parent route referred to as the index route, so you'd see something like ` .... `. – Drew Reese Oct 28 '22 at 09:15
  • If I set paths on children are they relative to parent if child has route "a" and parent has route "b", to access child should I visit: "b/a"? This is last question - thanks. –  Oct 28 '22 at 09:19
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/249131/discussion-between-drew-reese-and-john). – Drew Reese Oct 28 '22 at 09:20