在菜单组件中定义Route时,组件不会呈现

时间:2019-05-14 10:48:32

标签: javascript reactjs react-router react-router-v4

我正在尝试创建完全基于react-router的可重用菜单组件。我可以显示菜单项,但是当单击时,不会呈现需要呈现的组件。但是,如果我在菜单组件外部定义路由,例如在<Router>组件内部定义路由,那么它将起作用。我怎样才能使它以任何一种方式工作?

这是我的工作方式

Menu.js

const Menu = ({ children }) => {
  return (
    <>
      <Header padding>
        <Container>
          <Row>
            <NavTabs>{children}</NavTabs>
          </Row>
        </Container>
      </Header>
    </>
  );
};

export default Menu;

MenuItem.js

const MenuItem = ({ to, children, match }) => {
  return (
    <>
      <NavItem>
        <NavLink to={`${match.path}${to}`}>{children}</NavLink>
      </NavItem>
    </>
  );
};

export default withRouter(MenuItem);

这就是我的使用方式

const items = [
  { id: 1, name: "Home", path: "home", component: HomeC },
  { id: 2, name: "Jobs", path: "jobs", component: Jobs }
];

const Home = () => {
  return (
    <>
      Menu
      <Menu>
        {items.map(item => (
          <MenuItem key={item.id} to={item.path}>
            {item.name}
          </MenuItem>
        ))}
        {/* if Route is defined inside Menu component, render component from here only else from outside */}
        <>
          <Switch>
            <Route path="/home" component={HomeC} />
            <Route path="/jobs" component={Jobs} />
          </Switch>
        </>
      </Menu>
    </>
  );
};

export default Home;

这是演示的完整代码

https://codesandbox.io/s/vq0w113140

3 个答案:

答案 0 :(得分:0)

问题出在您的index.js中,您的路由器与/jobs的任何路由都不匹配。

  <Router>
    <Route exact path="/" component={Home} />
    <Route path="/hello" render={() => <h1>Hello</h1>} />
    <Route path="/home" render={() => <h1>Hello</h1>} />
  </Router>

您需要在此处为​​/jobs添加一条路线,或者,如果您想默认使用Home组件,请将这些路线包裹在Switch中并添加一个{{ 1}},底部没有Route,带有path=选项。


编辑-切换示例

component={Home}

在此示例中,除<Router> <Switch> <Route path="/hello" render={() => <h1>Hello</h1>} /> <Route path="/home" render={() => <h1>Hello</h1>} /> <Route component={Home} /> <Switch> </Router> /hello以外的任何其他路线都将渲染Home组件。开关的工作方式就像代码中的/home一样-它会从列表中选择匹配的第一个开关并进行渲染。如果没有匹配项,它将呈现列表中的最后一项。

这将允许您使用Home组件内部的作业路线来渲染Jobs组件,以包括菜单。

答案 1 :(得分:0)

您可以从Menu.js删除路线

并将它们放在Home Component Route下面的index.js中。

您可以使用以下代码:

Home.js:

  const Home = () => {
  return (
    <>
      Menu
      <Menu>
        {items.map(item => (
          <MenuItem key={item.id} to={item.path}>
            {item.name}
          </MenuItem>
        ))}
        {/* if Route is defined inside Menu component, render component from here only else from outside */}
        <></>
      </Menu>
    </>
  );
};

index.js: please remove exact in first route

function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Router>
        <Route path="/" component={Home} />
        <Route path="/jobs" render={() => <h1>jobs component</h1>} />
        <Route path="/home" render={() => <h1>Home component</h1>} />
      </Router>
    </div>
  );
}

这是工作代码链接:https://codesandbox.io/s/pjx7pv581j

答案 2 :(得分:0)

您可以使用Switch中的react-router-domSwitch仅返回一条第一条匹配路线。

function App() {
 return (
  <div className="App">
    <h1>Hello CodeSandbox</h1>
    <h2>Start editing to see some magic happen!</h2>
    <BrowserRouter>
      <Switch>
        <Route path="/" component={Home} />
        <Route path="/jobs" component={Jobs} />
      </Switch>
    </BrowserRouter>
  </div>
 );
}

这是我的解决方案:https://codesandbox.io/embed/wn4j5525n8