试图在react-router中返回“/”?

IT技术 reactjs react-router react-router-dom
2021-04-13 07:34:07

所以,我要的是有一个顶级路由App.js的路由到 Home的“/”。Home我想渲染一些东西,然后在一个地方我根据路径选择要渲染的内容。

即如果路径是“/”我想显示一个Link可以带我到“/about”的路径,如果路径是“/about”我会在About那里显示组件。

App.js我总是有一个Link可以带我回到“/”的。


所以App.js渲染这个:

  <Router>
    <div>          
      <Link to="/">
        <button>Go to home</button>
      </Link>
      <Route exact path="/" component={() => <Home/>} />
      <Route exact path="/other" component={() => <Other/>} />
    </div>
  </Router>

Home 渲染这个:

  <div>
    THIS IS HOME WOO!
    <Router>
      <div>
        <Route exact path="/" component={() => <HomeController/>} />
        <Route exact path="/about" component={() => <About/>} />
      </div>
    </Router>
  </div>

HomeController 渲染这个:

  <Link to="/about">
    <button>Go to about</button>
  </Link>

About呈现这个:

  <div>
    ABOUT
  </div>

当我启动应用程序时,它看起来像这样:

在此处输入图片说明

当我单击“转到约”时,它看起来像这样:

在此处输入图片说明

正确更新 url 和路由器显示的内容 Home

但是,如果我现在单击“回家”,则会发生这种情况:

在此处输入图片说明

正确更新 url 但在渲染时保留“关于”页面Home


为什么是这样?为什么“/”似乎仍然路由到“/about”?我需要更改什么才能使按钮路由回到“/”并再次显示“转到大约”按钮?

这是我用来重新创建问题的所有代码:pastebin

3个回答

有几件事你需要纠正。

首先,您的应用程序中必须只有一个路由器,而不是嵌套的路由器

其次,如果您在父路由上有一个精确的关键字,那么嵌套的路由将不匹配,因为匹配将在父级本身失败

第三,那么你不想将自定义props传递给子组件,你必须像component={Home}和不一样渲染它们component={() => <Home/>},如果你想将props传递给孩子,你必须使用renderand not componentprop 并写render={(props) => <Home test="1" {...props}}

你的完整代码看起来像

import React, { Component } from "react";
import { render } from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

class App extends Component {
  render() {
    return (
      <div className="App">
        <Router>
          <div>
            <Link to="/">
              <button>Go to home</button>
            </Link>
            <Route path="/" component={Home} />
            <Route exact path="/other" component={Other} />
          </div>
        </Router>
      </div>
    );
  }
}

class Home extends Component {
  render() {
    return (
      <div className="home">
        <div>
          <Route exact path="/" component={HomeController} />
          <Route exact path="/about" component={About} />
        </div>
      </div>
    );
  }
}

class HomeController extends Component {
  render() {
    return (
      <div className="homecontroller">
        <Link to="/about">
          <button>Go to about</button>
        </Link>
      </div>
    );
  }
}

class About extends Component {
  render() {
    return <div className="about">ABOUT</div>;
  }
}

class Other extends Component {
  render() {
    return <div className="other">OTHER</div>;
  }
}

render(<App />, document.getElementById("root"));

工作演示

您可以参考以下问题了解更多详情

将自定义props传递给 react-router v4 中的路由器组件

React Router 4 嵌套路由未呈现

@MrJalapeno,它确实有效,但是使用渲染是一种很好的做法,请参考我在答案中添加的第一个链接,它会向您解释为什么需要 {...props}
2021-06-03 07:34:07
谢谢你的好回答!前两点解决了问题。最后一部分的问题是:为什么会这样?例如,在我的真实代码中,我现在有这条路线:<Route exact path={routes.SELECT} component={() => <Select model={model} explorable={this.state.explorable}/>} />它可以工作,在Select我可以访问modelexplorable通过this.props. 所以我假设我不想这样做是有原因的?{...props}部分是什么意思
2021-06-06 07:34:07

删除<Router />条目Home

App.js 我注意到/other列出而不是RouteAbout组件进行以下调整/about如果它是正确的,不要管它,否则将其调整About为如下组件。您确实需要在顶部导入这些组件,所以我假设您已经这样做了。

  <Router>
    <div>          
      <Link to="/">
        <button>Go to home</button>
      </Link>
      <Route exact path="/" component={Home} />
      <Route exact path="/about" component={About} />
    </div>
  </Router>

因为Home.js,你需要渲染<HomeController />

  <div>
    THIS IS HOME WOO!
    <HomeController />
  </div>
谢谢,但它并没有解决我的泡菜:(开“/关于”我想渲染About 里面Home,那就是,我想看看双方的内容Home(“这是HOME WOO”)和内容About(“关于” ) 在它替换 HomeController(“转到关于”按钮)的地方我想知道我是否正在采取一些根本性的错误路径来解决这个问题。
2021-06-04 07:34:07

我需要进行以下更改:

App.js: 将Router改为Switch,改变Routes的顺序,设置“/”为相对路径

<Switch>
  <Route exact path="/other" component={() => <Other/>} />
  <Route path="/" component={() => <Home/>} />
</Switch>

从以下位置删除路由器Home

<div>
  THIS IS HOME WOO!
  <div>
      <Route exact path="/" component={() => <HomeController/>} />
      <Route exact path="/about" component={() => <About/>} />
  </div>
</div>