【问题标题】:Use onClick to change path in a non-Router component in React使用 onClick 在 React 中更改非路由器组件中的路径
【发布时间】:2020-05-08 18:34:10
【问题描述】:

我有一个具有以下简化结构的 React 应用程序:

function App(props) {
    return (
        <Navbar />
        <Router>
            <Route exact path="/profile/" component={Profile} />
            <Route exact path="/" component={Home} />
        </Router>
    );
}

Navbar 组件中,我有一个logout 的按钮,这意味着我需要:

  1. 从存储中删除身份验证令牌(简单地为一般情况做一个逻辑),并且
  2. 将用户路由到登录页面。

我尝试使用该按钮的onClick 并使用this.props.history.push('/') 更改路径,但这不起作用(它抱怨historyundefined),因为我的导航栏是在路由器外部定义的.

我的问题是,是否可以将Navbar 移动到我的路由器组件内部并在所有页面中都相同时重复它?或者有没有可以用来更改浏览器路径的防重复解决方案?

【问题讨论】:

  • 我觉得把它放在路由器里面就好了,我不认为如果路由改变了Navbar会重新渲染。
  • 谢谢,您提到导航栏在更改路线时未呈现很有帮助。

标签: reactjs react-router


【解决方案1】:

可以将&lt;Navbar&gt; 插入到路由器中。我的设置往往是

<Router>
    <div className="app-container">
      <Navigation />
      <div className="content">
        <Switch>
          (Routes go here)
        </Switch>
      </div>
    </div>
</Router>

【讨论】:

  • 我现在如何在Navigation 中访问history?我对我来说是不确定的。 (我应该将任何props 传递给Navigation 吗?
  • 使用useHistory 钩子。
  • 如果Navbar不是函数组件,怎么办?
  • 您可以使用withRouter() 函数,然后与this.props.history 一起使用。更多信息:reacttraining.com/react-router/web/api/withRouter
【解决方案2】:

是的! 尝试在您的导航栏中使用&lt;Switch&gt;in 路由器和&lt;Link&gt;

export default function App() {
  return (
    <Router>
      <Navbar />
        // inside Navbar try using <Link to="/">Logout</Link>
        {/* A <Switch> looks through its children <Route>s and
            renders the first one that matches the current URL. */}
        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/users">
            <Users />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch> 
    </Router>
  );
}

https://reacttraining.com/react-router/web/guides/quick-start

【讨论】:

  • 我现在可以访问Navbar 中的history 对象吗?因为我不想使用Link 简单地重定向到主页,所以我还想清除存储中的身份验证。
  • 由于你使用函数组件,你可以试试 const { history } = useHistory();然后你可以毫无问题地访问历史。试一试。
  • @WesleyLoh 谢谢。在这种情况下,我是否需要在 Router 中包含 Navbar
【解决方案3】:

路由侦听路由器上下文提供的历史 API,并且由于 Navbar 在其外部呈现,因此它们不会反映更改。

解决方案是将Router包裹在navbar周围,同时将NAvbar渲染为默认路由

function App(props) {
    return (
       <Router>
          <>
            <Route component={Navbar}/>
            <Route exact path="/profile/" component={Profile} />
            <Route exact path="/" component={Home} />
          </>
        </Router>
    );
}

【讨论】:

  • 我不知道为什么有人对你的答案投了反对票(如果我知道这里出了什么问题,我会很高兴),但我最终得到了一个类似的解决方案来传递 Routeprops到我的Navbarhistory 访问:&lt;Route render={(props) =&gt; (&lt;Nabvar {...props} /&gt;)} /&gt;
  • @AliTou,需要将 Navbar 渲染为 Route,以便它可以使用 Router Props
  • 是的,这是其他答案没有考虑到的。
猜你喜欢
  • 2018-01-03
  • 1970-01-01
  • 2018-02-24
  • 2019-07-19
  • 2020-10-10
  • 2022-07-21
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多