前言
手动路由跳转是React Router中一个重要的概念,它允许您在React应用程序中通过编程方式控制路由导航,而不是依赖于用户的交互操作。这种能力对于实现复杂的导航逻辑、处理表单提交、或基于某些条件进行路由跳转非常有用。
在这篇文章中,我们将深入探讨如何在React应用程序中执行手动路由跳转。您将学习如何使用React Router提供的useHistory或useNavigate钩子(或者类似的方法,取决于您的React Router版本)来获取路由导航的函数,并如何在组件内部触发路由跳转。我们还会讨论如何传递参数或状态给目标路由。
手动路由跳转
不通过 Link/NavLink 来设置资源地址, 而是通过 JS 来设置资源地址。
- 如果是 Hash 模式, 那么只需要通过 JS 设置 Hash 值即可
更改 App.js 的路由模式为 Hash 模式:
import React from 'react'; import Home from './components/Home' import About from './components/About' import Other from './components/Other' import User from './components/User' import Login from './components/Login' import Discover from './components/Discover' import {BrowserRouter, HashRouter, NavLink, Route, Switch} from 'react-router-dom'; class App extends React.PureComponent { render() { return ( <div> <HashRouter> <NavLink to={'/home'} activeStyle={{color: 'red'}}>Home</NavLink> <NavLink to={'/about'} activeStyle={{color: 'red'}}>About</NavLink> <NavLink to={'/user'} activeStyle={{color: 'red'}}>User</NavLink> <NavLink to={'/discover'} activeStyle={{color: 'red'}}>广场</NavLink> <Switch> <Route exact path={'/home'} component={Home}/> <Route exact path={'/about'} component={About}/> <Route exact path={'/user'} component={User}/> <Route exact path={'/login'} component={Login}/> <Route path={'/discover'} component={Discover}/> <Route component={Other}/> </Switch> </HashRouter> </div> ) } } export default App;
在更改 Discover.js 添加一个按钮在按钮的点击事件当中,手动的通过 JS 修改 Hash:
import React from 'react'; import {NavLink, Switch, Route} from "react-router-dom"; function Hot() { return ( <div>推荐</div> ) } function TopList() { return ( <div>排行榜</div> ) } function PlayList() { return ( <div>歌单</div> ) } class Discover extends React.PureComponent { render() { return ( <div> <NavLink exact to={'/discover'} activeStyle={{color: 'red'}}>推荐</NavLink> <NavLink exact to={'/discover/toplist'} activeStyle={{color: 'red'}}>排行榜</NavLink> <NavLink exact to={'/discover/playlist'} activeStyle={{color: 'red'}}>歌单</NavLink> <button onClick={() => { this.btnClick() }}>歌单 </button> <Switch> <Route exact path={'/discover'} component={Hot}/> <Route exact path={'/discover/toplist'} component={TopList}/> <Route exact path={'/discover/playlist'} component={PlayList}/> </Switch> </div> ) } btnClick() { window.location.hash = '/discover/playlist'; } } export default Discover;
- 如果一个组件是通过路由创建出来的, 那么系统就会自动传递一个
history
给我们 - 我们只需要拿到这个 history 对象, 调用这个对象的
push
方法, 通过 push 方法修改资源地址即可
更改 App.js 的路由模式为 BrowserRouter 然后在更改 Discover.js 的按钮点击事件的实现方法代码即可:
btnClick() { this.props.history.push('/discover/playlist'); }
手动路由跳转注意点
在看注意点之前首先,我们更改 App.js 的代码,在该组件当中进行广场路由的手动路由跳转的实现,首先看 Hash 模式的跳转:
import React from 'react'; import Home from './components/Home' import About from './components/About' import Other from './components/Other' import User from './components/User' import Login from './components/Login' import Discover from './components/Discover' import {BrowserRouter, HashRouter, NavLink, Route, Switch} from 'react-router-dom'; class App extends React.PureComponent { render() { return ( <div> <HashRouter> <NavLink to={'/home'} activeStyle={{color: 'red'}}>Home</NavLink> <NavLink to={'/about'} activeStyle={{color: 'red'}}>About</NavLink> <NavLink to={'/user'} activeStyle={{color: 'red'}}>User</NavLink> <NavLink to={'/discover'} activeStyle={{color: 'red'}}>广场</NavLink> <button onClick={() => { this.btnClick() }}> 广场 </button> <Switch> <Route exact path={'/home'} component={Home}/> <Route exact path={'/about'} component={About}/> <Route exact path={'/user'} component={User}/> <Route exact path={'/login'} component={Login}/> <Route path={'/discover'} component={Discover}/> <Route component={Other}/> </Switch> </HashRouter> </div> ) } btnClick() { window.location.hash = '/discover'; } } export default App;
点击了按钮之后是可以进行跳转的,然后在看 BrowserRouter 的情况通过 history 跳转,发现报了一个 Cannot read property 'push' of undefined
那么这个就是本次要介绍的一个注意点,只有通过路由创建出来的组件才有 history
对象, 所以不能在根组件中使用手动路由跳转,如果一个组件是通过路由创建的, 那么系统就会自动给这个组件传递一个 history 对象,但是如果一个组件不是通过路由创建的, 那么系统就不会给这个组件传递一个 history 对象,如果现在在非路由创建出来的组件中使用 history 对象, 那么可以借助 withRouter
高阶组件,只要把一个组件传递给 withRouter
方法, 那么这个方法就会通过路由将传入的组件创建出来,如果一个组件要使用路由创建, 那么这个组件必须包裹在 BrowserRouter, HashRouter 中。
更改 index.js:
import ReactDOM from 'react-dom'; import React from 'react'; import App from './App'; import {BrowserRouter} from 'react-router-dom'; ReactDOM.render( <BrowserRouter> <App/> </BrowserRouter>, document.getElementById('root'));
App.js:
import React from 'react'; import Home from './components/Home' import About from './components/About' import Other from './components/Other' import User from './components/User' import Login from './components/Login' import Discover from './components/Discover' import {NavLink, Route, Switch, withRouter} from 'react-router-dom'; class App extends React.PureComponent { render() { return ( <div> <NavLink to={'/home'} activeStyle={{color: 'red'}}>Home</NavLink> <NavLink to={'/about'} activeStyle={{color: 'red'}}>About</NavLink> <NavLink to={'/user'} activeStyle={{color: 'red'}}>User</NavLink> <NavLink to={'/discover'} activeStyle={{color: 'red'}}>广场</NavLink> <button onClick={() => { this.btnClick() }}> 广场 </button> <Switch> <Route exact path={'/home'} component={Home}/> <Route exact path={'/about'} component={About}/> <Route exact path={'/user'} component={User}/> <Route exact path={'/login'} component={Login}/> <Route path={'/discover'} component={Discover}/> <Route component={Other}/> </Switch> </div> ) } btnClick() { this.props.history.push('/discover'); } } export default withRouter(App);
最后
本期结束咱们下次再见👋~
🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗