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);
posted @ 2022-05-17 01:52  BNTang  阅读(1483)  评论(0编辑  收藏  举报