react声明式导航和编程式导航

2,523 阅读4分钟

react中的两种路由导航方法【声明式导航、编程式导航】

主要使用的方法Link , NavLink , props, useHistory() ,Route】,推荐使用前四个方法,更简单高效

1、声明式导航 【Link,NavLink】

声明式导航自己主要用到的是react中的两个路由组件【Link、NavLink】。其中Link组件的导航方式和HMTL中的a标签类似,在react将虚拟DOM渲染成真实DOM后,Link组件也被渲染成了a标签。下面看一下例子顺便在代码中附上react中的路由懒加载方式Link 方式

import React, { Component,lazy,Suspense } from 'react'//导入了路由懒加载模块
import { Route,Redirect,Link} from 'react-router-dom'
import Login from '../Login/index'
const lazyComponent = lazy(() => import('../lazyComponent')); //使用路由懒加载的方式加载组件
export default class World extends Component {
  render() {
    return (
      <div className='worldFrame'>
        {/* 使用路由 */}
        <ul>
          <li>
            <h1>
            {/*使用Link跳转,同时携带参数ID*/}
            <Link to={`/login/${id}`} className='red'>跳转到Login</Link>
            <br />
            <Link to="/lazyComponent" className='red'>跳转到路由懒加载组件</Link>
            </h1>
          </li>
        </ul>
        <hr /> 
        <ul>
          <li>
          {/*渲染路由组件Login到该位置,同时接收到路由参数ID*/}
              <Route path='/login/:id' component={Login}></Route>
              {/*重定向*/}
              <Redirect to='/'></Redirect>
          </li>
          <li>
          {/*使用路由懒加载的模块,路由组件未加载出来前会以Loading字符显示在页面中*/}
            <Suspense fallback={<h1 style={{color:'skyblue'}}>Loading...</h1>}>
              <Route path="/lazyComponent" component={lazyComponent}></Route>
            </Suspense>
          </li> 
        </ul>
        <br />
      </div>
    )
  }
}

NavLink 方式 NavLink方式相当于Link的加强版,主要的属性有

activeClassName(string):设置选中样式,默认值为active activeStyle(object):当元素被选中时,为此元素添加样式 exact(bool):为true时,只有当导致和完全匹配class和style才会应用 strict(bool):为true时,在确定为位置是否与当前URL匹配时,将考虑位置pathname后的斜线 isActive(func)判断链接是否激活的额外逻辑的功能

需要查看【Link、NavLink】的主要区别在这里附上 CSDN 博文一篇 blog.csdn.net/lhjuejiang/… 如下代码,在被点击时可以显示路径对应的背景色,路径相同时则显示相同的背景色

import { NavLink} from 'react-router-dom'
import React from 'react'
import './index.scss'
export default function Aside(){
  return(
   <React.Fragment>
     <ul className='links'>
       <li>
         <NavLink activeClassName="selected" to='/aside'>二级菜单</NavLink>
       </li>
       <li>
         <NavLink activeClassName="selected" to='/asid'>二级菜单</NavLink>
       </li>
       <li>
         <NavLink activeClassName="selected" to='/asi'>二级菜单</NavLink>
       </li>
       <li>
         <NavLink activeClassName="selected" to='/as'>二级菜单</NavLink>
       </li>
     </ul>
   </React.Fragment>
 )
}

scss中的代码: 在这里插入图片描述

2、编程式导航 【props, useHistory() , Route】

2.1 利用已注册路由组件的props

这个属性的唯一缺点就是使用时需要在已注册的路由组件中使用,如果该组件不是路由组件,则props对象中将不会有需要使用的路由参数(如果父组件没有给子组件传参,props会是一个空对象)。 请看下列代码,Aside和AsideTwo、AsideThree都已被注册成路由组件

import { Route, Redirect, Switch, BrowserRouter } from 'react-router-dom';
import { Component } from 'react';
import Aside from './views/Aside';
import AsideTwo from './views/Aside/AsideTwo';
import AsideThree from './views/Aside/AsideThree';

export default class App extends Component {
  render(){

    return (
      <div className="App">
        <BrowserRouter>
          <aside className='content'>
            <Switch>
            	{/*注册路由组件*/}
              <Route path="/aside" component={Aside}></Route>
              <Route path="/aside2" component={AsideTwo}></Route>
              <Route path="/aside3" component={AsideThree}></Route>
              {/*重定向*/}
              <Redirect to='/aside'></Redirect>
            </Switch>
        </BrowserRouter>
      </div>
    )
  }
}

函数式组件实现路由跳转 函数组件中可以通过传参来直接使用props

import './index.sass'
export default function AsideTwo(props){
  const changeLink = ()=>{
    // console.log('@@@@@',props)
    props.history.push('/aside')
  }
  return(
   <>
   <h1>主要视图区</h1>
   <h3>主要展示区2</h3>
   <button onClick={changeLink}>跳转到/aside</button>
   </>
 )
}

类式组件实现路由跳转 类式组件中使用this.props使用props 注意: 在类式组件中使用props时的事件方法,需要写成箭头函数,避免造成this指向不正确的问题

import { Component } from 'react'
import './index.sass'
export default class AsideThree extends Component{
  changLink = ()=>{
    this.props.history.push('/aside')
    console.log('MMMM',this.props);
  }
  render(){
    return(
     <>
      <h1>主页面视图</h1>
      <h3>主要展示区1</h3>
      <button onClick={this.changLink}>跳转到/aside</button>
     </>
   )
  }
}

2.2、在没有注册路由的组件中使用编程式导航

2.2.1 useHistory() 钩子(hook)来做函数式组件的编程式导航,下列为示例代码: 注意: 该钩子函数只能用于函数组件

import { useHistory } from 'react-router';//导入useHistory钩子
import { Button } from 'antd';
export default function Header(){
  let history = useHistory() //将useHistory()钩子赋值给history方便使用
  let programmingLink = function(){
    history.push('/home')//点击按钮后使用push方法跳转到对应的路由位置
  }
  
  return(
   <div className='header'>
      <div className='btns'>
        <Button type="primary" onClick={programmingLink} ghost>Dashed</Button>
      </div>
   </div>
 )
}

2.2.2 在类式组件中需要进行编程式跳转【使用Route组件的render属性】

import { Component } from 'react'
import { Route } from 'react-router'
export default class Footer extends Component {
  render () {
    return (
      <>
        <Route render={({ history }) => (<button onClick={() => { history.push('/changLink') }}>点击更换路由</button>)} />
      </>
    )
  }
}

注意:该方法使用push进去的路由需要是已经在Route组件中注册的路由,如果路由未注册,则无法跳转

需要其他方法在类式组件编程式跳转,可以看下博客园的这篇博客 www.cnblogs.com/panrui1994/…