无废话 | 快速上手React路由(下)

简介: 接上文。

路由传参


所有路由传递的参数,都会在跳转路由组件的 props 中获取到,每种传参方式接收的方式略有不同


路由传参的方式一共有三种,依次来看一下


第一种


第一种是在 Link 组件的跳转路径上携带参数,并在 Route 组件的匹配路径上通过 :参数名 的方式接收参数,代码如下:


import { 
  BrowserRouter as Router, 
  Route, 
  NavLink,
  Switch,
} from 'react-router-dom'
import Home from './home'
import About from './about'
function App() {
  return (
    <div className="App">
      <Router>
        {/* 在 /home 的路径上携带了 张三、18 共两个参数 */}
        <NavLink to="/home/张三/18" className="link">跳转Home页面</NavLink>   
        <NavLink to="/about" className="link">跳转About页面</NavLink>
        <Switch>
          {/* 在 /home 匹配路径上相同的位置接收了 name、age 两个参数 */}
          <Route path="/home/:name/:age" component={Home}/>       
          <Route path="/about" component={About}/>                           
        </Switch>
      </Router>
    </div>
  );
}
export default App;


尝试跳转,并打印一下路由组件的 props


8ff566c852f611dc511d8d304d86068a.jpg


可以看到,第一种方式的参数是通过 props.match.params 来获取的


第二种


第二种方式就是通过在 Link 组件的跳转链接后面跟上以 ? 开头,类似 ?a=1&b=3 这样的参数进行传递,代码如下:


import { 
  BrowserRouter as Router, 
  Route, 
  NavLink,
  Switch,
} from 'react-router-dom'
import Home from './home'
import About from './about'
function App() {
  return (
    <div className="App">
      <Router>
        {/* 在跳转路径后面以?开头传递两个参数,分别为name=张三、age=18 */}
        <NavLink to="/home?name=张三&age=18" className="link">跳转Home页面</NavLink>   
        <NavLink to="/about" className="link">跳转About页面</NavLink>
        <Switch>
          {/* 此处无需做接收操作 */}
          <Route path="/home" component={Home}/>       
          <Route path="/about" component={About}/>                           
        </Switch>
      </Router>
    </div>
  );
}
export default App;


尝试跳转,并打印一下路由组件的 props


a90d0aed811d2352d1a2a76647b8257b.jpg

可以看到,第二种方式的参数是通过 props.location.search 来获取的,不过这里的参数需要自己简单做进一步转化,这里就不做过多说明了


第三种


第三种方式就是以对象的形式编写 Link 组件的 to 跳转属性,并通过 state 属性来传递参数,代码如下:


import { 
  BrowserRouter as Router, 
  Route, 
  NavLink,
  Switch,
} from 'react-router-dom'
import Home from './home'
import About from './about'
function App() {
  return (
    <div className="App">
      <Router>
        {/* 以对象的形式描述to属性,路径属性名为pathname,参数属性名为state */}
        <NavLink to={{pathname: "/home", state: {name: '张三', age: 18}}} className="link">跳转Home页面</NavLink>   
        <NavLink to="/about" className="link">跳转About页面</NavLink>
        <Switch>
          {/* 此处无需特地接收属性 */}
          <Route path="/home" component={Home}/>       
          <Route path="/about" component={About}/>                           
        </Switch>
      </Router>
    </div>
  );
}
export default App;


尝试跳转,并打印一下路由组件的 props


f39d5a3d627d909a4d222966e2fa040a.jpg


可以看到,第三种方式的参数是通过 props.location.state 来获取的


函数式路由


以上主要都是通过 react-router-dom 中的 Link 组件来往某个路由组件跳转


但有时,我们需要更灵活的方式进行跳转路由,例如通过调用一个函数,随时随地进行路由跳转,这就叫函数式路由


函数式路由用到的方法有以下 5 个(下方截图来自路由组件props


c8bc455cbc1743ddbac86d449ca17cd2.jpg


5 个方法分别是 pushreplacegoForwardgoBackgo,接下来按顺序介绍一下这几个方法


push


push 方法就是使页面跳转到对应路径,并在浏览器中留下记录(即可以通过浏览器的回退按钮,返回上一个页面)


举个例子:在路由组件 Home 中设置一个按钮 button ,点击后调用 push 方法,跳转到 /about 页面


import React from 'react'
function Home (props) {
    let pushLink = () => {
        props.history.push('/about')
    }
    return (
        <div className="a">
            我是Home页面
            <button onClick={pushLink}>跳转到about页面</button>
        </div>
    )
}
export default Home


跳转效果如下:


bd63014c95eb892eade303e4cd6c0dfd.jpg


可以看到,通过 push 方法跳转以后,可以通过浏览器的回退按钮,返回上一个页面


replace


replace 方法与 push 方法类似,不一样的地方就是,跳转后不会在浏览器中保存上一个页面的记录(即无法通过浏览器的回退按钮,返回上一个页面)


改动一下代码


import React from 'react'
function Home (props) {
    let replaceLink = () => {
        props.history.replace('/about')
    }
    return (
        <div className="a">
            我是Home页面
            <button onClick={replaceLink}>跳转到about页面</button>
        </div>
    )
}
export default Home


跳转效果如下:


419e1a87e556fd429d60ddcdbad65995.jpg


可以看到,刚开始的路径是 '/' ,然后跳转到 '/home' ,再点击按钮,通过 replace 方法跳转到 /about 页面。最后通过浏览器的回退按钮返回到了 / 页面,说明中间的 /home 没有被存在浏览器的记录里


goForward


调用 goForward 方法,就相当于点击了浏览器的返回下一个页面按钮,如下图所示:


acba8e53befd66744d5b4c3bde63ad8f.jpg


这里就不做过多演示了


goBack


调用 goBack 方法,就相当于点击了浏览器的返回上一个页面的按钮,如下图所示:


87873bae72175ca586c8e173c01cab50.jpg

go


go 方法顾名思义,是用于跳转到指定路径的。


该方法接受一个参数(参数类型为 Number),情况如下:


  1. 当参数为正数 n 时,表示跳转到下 n 个页面。例如 go(1) 相当于调用了一次 goForward 方法


  1. 当参数为负数 n 时,表示跳转到上 n 个页面。例如 go(-3) 相当于调用了三次 goBack 方法


  1. 当参数为 0 时,表示刷新当前页面


普通组件使用路由


这里区分两个概念,分别为 普通组件路由组件


通过 Route 组件渲染的组件为路由组件 ,其余的基本上都为 普通组件


例如,下方代码中:Home 组件为路由组件 ; App 组件为普通组件


import {
  BrowserRouter as Router, 
  Route, 
  NavLink,
  Switch,
} from 'react-router-dom'
import Home from './home'
export default function App() {
  return (
    <div className="App">
      <Router>
        <NavLink to='/home' className="link">跳转Home页面</NavLink>   
        <Switch>
          <Route path="/home" component={Home}/>                              
        </Switch>
      </Router>
    </div>
  );
}


然后,路由组件跟普通组件最大的区别就是,组件的 props 属性中是否有下图所示的内容:(前者有,后者无)


bc938f2e898ff504812991a0b15ebba7.jpg


此时,react-router-dom 提供了一个 withRouter 方法,可以使普通组件也能像路由组件一样有那些方法或数据可以使用


使用方法如下:


import { 
  BrowserRouter as Router, 
  Route, 
  NavLink,
  Switch,
  withRouter,  // 1. 引入 witRouter
} from 'react-router-dom'
import About from './about'
function App(props) {
  console.log(props);   // 3. 尝试打印普通组件App的props,发现此时props中已有内容了,即普通组件也能拥有跟路由组件一样类似的功能
  return (
    <div className="App">
      <Router>
        <NavLink to="/about" className="link">跳转About页面</NavLink>
        <Switch>
          <Route path="/about" component={About}/>                           
        </Switch>
      </Router>
    </div>
  );
}
export default withRouter(App);  // 2. 通过withRouter方法对普通组件做一层包装处理


补充


replace


在函数式路由里跳转类型主要有两种,分别是 pushreplace,那么在非函数式路由中,同样也可以自定义跳转类型,具体的实现代码如下:


import { 
    BrowserRouter as Router, 
    Route, 
    Link 
} from 'react-router-dom'
import Home from './home'
import About from './about'
function App() {
  return (
    <div className="App">
      <Router>
        <Link to="/home" className="link">跳转Home页面</Link>
        <Link to="/about" className="link">跳转About页面</Link>
        <Route path="/home" component={Home} replace={true}/>  {/* replace为true,跳转类型为replace */}
        <Route path="/about" component={About} replace={false}/>   {/* replace为false,跳转类型为push */}
      </Router>
    </div>
  );
}
export default App;


Route 组件上有个 replace 属性可以设定跳转类型,当值为 true 时,跳转类型为 replace ; 为 false 时,跳转类型为 push


excat


路由的匹配默认是模糊匹配的,举个例子:


import { 
  BrowserRouter as Router, 
  Route, 
  Link,
} from 'react-router-dom'
import Home from './home'
import About from './about'
function App() {
  return (
    <div className="App">
      <Router>
        <Link to="/home/abc">跳转Home页面</Link>    {/* 跳转到/home/abc,但实际home下没有abc这个路由组件 */}
        <Link to="/about/abc">跳转About页面</Link>  {/* 跳转到/about/abc,但实际home下也没有abc这个路由组件 */}
        <Route path="/home" component={Home} />    {/* 路由匹配规则为/home,没有设置exact属性,当前为模糊匹配 */}
        <Route path="/about" component={About} exact/>   {/* 路由匹配规则为/about,设置了exact属性,当前为精准匹配 */}
      </Router>
    </div>
  );
}
export default App;


效果如下:


d1c291622fa50a9343a38c7f91b1b53d.jpg


图中看出,因为跳转 /home/abc 时,第一个 Route 组件是模糊匹配的,所以先匹配到了 /home,因此 Home 组件渲染了 ; 而跳转 /about/abc 时,第二个 Route 组件是精准匹配的,即 /about/abc 不等于 /about,所以 About 组件也没有渲染


总结:


  1. 如果想要精准匹配的话,只需要将 Route 组件的 exact 属性设置为 true 即可


  1. 精准匹配要谨慎使用,因为可能会影响嵌套路由的使用


相关文章
|
前端开发 JavaScript
React项目路由懒加载lazy、Suspense,使第一次打开项目页面变快
本文介绍了在React项目中实现路由懒加载的方法,使用React提供的`lazy`和`Suspense`来优化项目首次加载的速度。通过将路由组件改为懒加载的方式,可以显著减少初始包的大小,从而加快首次加载速度。文章还展示了如何使用`Suspense`组件包裹`Switch`来实现懒加载过程中的fallback效果,并提供了使用前后的加载时间对比,说明了懒加载对性能的提升作用。
790 2
React项目路由懒加载lazy、Suspense,使第一次打开项目页面变快
|
11月前
|
前端开发 API UED
React 路由守卫 Guarded Routes
【10月更文挑战第26天】本文介绍了 React 中的路由守卫(Guarded Routes),使用 `react-router-dom` 实现权限验证、登录验证和数据预加载等场景。通过创建 `AuthContext` 管理认证状态,实现 `PrivateRoute` 组件进行路由保护,并在 `App.js` 中使用。文章还讨论了常见问题和易错点,提供了处理异步操作的示例,帮助开发者提升应用的安全性和用户体验。
408 1
|
7月前
|
前端开发 UED
在React Router中,如何处理路由的404错误页面?
在React Router中,如何处理路由的404错误页面?
271 57
|
7月前
|
前端开发
如何在React Router中进行路由重定向?
如何在React Router中进行路由重定向?
443 57
|
移动开发 资源调度 前端开发
介绍React路由模式
【8月更文挑战第10天】介绍React路由模式
164 12
|
前端开发 JavaScript 网络架构
实现动态路由与状态管理的SPA——使用React Router与Redux
【10月更文挑战第1天】实现动态路由与状态管理的SPA——使用React Router与Redux
340 95
|
11月前
|
前端开发 安全 网络安全
React——路由Route
React——路由Route
126 2
React——路由Route
|
12月前
|
资源调度 前端开发 测试技术
React Router 路由管理
【10月更文挑战第10天】本文介绍了 React Router,一个在 React 应用中管理路由的强大工具。内容涵盖基本概念、安装与使用方法、常见问题及解决方案,如路由嵌套、动态路由和路由守卫等,并提供代码示例。通过学习本文,开发者可以更高效地使用 React Router,提升应用的导航体验和安全性。
784 19
|
前端开发 网络架构
React 路由
10月更文挑战第11天
113 2
|
前端开发 Python
React技术栈-React路由插件之自定义组件标签
关于React技术栈中React路由插件自定义组件标签的教程。
181 4
React技术栈-React路由插件之自定义组件标签