博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react 路由
阅读量:2121 次
发布时间:2019-04-30

本文共 7638 字,大约阅读时间需要 25 分钟。

React路由

什么是路由?

路由是根据不同的 url 地址展示不同的内容或页面。 一个针对React而设计的路由解决方案、可以友好的帮你解决React components 到 URl之间的同步映射关系。

  • 如果要使用 路由模块,第一步,安装 react-router-dom
  • 第二步,导入 路由模块

路由安装

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

使用React路由之前,我们需要先安装 react-router-dom这个包。比如:

npm install --save react-router-dom

路由使用

(1) 路由方法导入

import React from 'react'import {
HashRouter, Route, Redirect, Switch, NavLink } from 'react-router-dom'

(2) 定义路由以及重定向

  • HashRouter :表示一个路由的跟容器,将来,所有的路由相关的东西,都要包裹在 HashRouter 里面,而且,一个网站中,只需要使用一次 HashRouter 就好了;

    • 当 使用 HashRouter 把 组件的元素包裹起来之后,网站就已经启用路由了
    • 在一个 HashRouter 中,只能有唯一的一个根元素
    • 在一个网站中,只需要使用 唯一的一次 即可
  • Route :表示一个路由规则, 在 Route 上,有两个比较重要的属性, path component

    • Route 创建的标签,就是路由规则,其中 path 表示要匹配的路由,component 表示要展示的组件
    • 在 vue 中有个 router-view 的路由标签,专门用来放置,匹配到的路由组件的,但是,在 react-router 中,并没有类似于这样的标签,而是 ,直接把 Route 标签,当作的 坑(占位符)
    • Route 具有两种身份:1. 它是一个路由匹配规则; 2. 它是 一个占位符,表示将来匹配到的组件都放到这个位置
  • Redirect:内置两个属性 from : 匹配到的路径 to :要跳转的路径

    {
    props.children}
    {
    /* 动态路由 */}

完整代码如下:

//配置路由-路由组件import React from 'react'import {
HashRouter,Route,Redirect,Switch} from 'react-router-dom'import Center from '../views/Center'import Cinema from '../views/Cinema'import Detail from '../views/Detail'import Film from '../views/Film'export default function MRouter(props) {
return (
{
props.children}
{
/* 动态路由 */}
{
/* 模糊匹配 */}
)}/*function Route(props){ console.log(props.path) if(location.hash===props.path){ return
} return null}*/

注意:

a. <Redirect from="/" to="/film"/>

b. exact 精确匹配 (Redirect 即使使用了exact, 外面还要嵌套Switch 来用)

c. Warning: Hash history cannot PUSH the same path; a new entry will not be added to the history stack,这个警告只有在hash 模式会出现。在NavLink 加上 replace 来解决.

模糊匹配与精准匹配

默认情况下,路由中的匹配规则,是模糊匹配的。上面这种匹配方式,全都匹配到了cinema组件,不会匹配到search组件。

如果想让路由规则,进行精确匹配,可以为Route添加 exact 属性。

(3)嵌套路由

import React from 'react'import {
Route, Switch,Redirect } from 'react-router-dom'import Comingsoon from './films/Comingsoon'import Nowplaying from './films/Nowplaying'export default function Film() {
return (
大轮播
)}

(4)路由跳转方式

i. 声明式导航

  • Link :表示一个路由的链接(a链接),就好比 vue 中的 <router-link to=""></router-link>

  • NavLink (有高亮)

    • to:要跳转的路径(相当于a标签中的"herf"属性)
    • activeClassName:用来做选中样式的切换(相当于vue的 active-class )
import React from 'react'import {
NavLink} from 'react-router-dom'import './Tabbar.css'export default function Tabbar() {
return (
  • 电影
  • 影院
  • 我的
)}/* function NavLink(props){ return {props.childrenm} }*/

ii. 编程式导航

  • vue 使用this.$router.push()
  • react 使用 props.history.push()
const handleChange = (id)=>{
props.history.push(`/detail/${
id}`)}
动态路由:

用来路由跳转的过程中传递参数,例如点击列表页某条数据,跳转到详细页。

定义动态路由:

跳转到指定动态路由:

const handleChange = (id)=>{
props.history.push(`/detail/${
id}`)}
  • handleChange(item.filmId)}>{
    item.name}
  • 如果我想在 Detail组件中显示路由的参数,可以通过 props.match.params获取路由中的参数。

    • vue: this.$route.params.id

    • react: props.match.params.id

    useEffect(() => {
    console.log("获取详情id,发ajax给后端",props.match.params.id) }, [props.match.params.id])
    {
    this.props.match.params.id}

    完整代码如下:

    import {
    useEffect,useState} from 'react'import axios from 'axios'export default function Nowplaying(props) {
    const [list, setlist] = useState([]) useEffect(() => {
    axios.get("/test.json").then(res=>{
    setlist(res.data.data.films) }) }, []) const handleChange = (id)=>{
    //编程式导航 props.history.push(`/detail/${
    id}`) } return (
    {
    list.map(item=>
  • handleChange(item.filmId)}> { {
    item.name}
  • ) }
    )}

    (5) 路由传参

    (1)this.props.history.push({
    pathname : '/user' ,query : {
    day: 'Friday'} }) this.props.location.query.day (2) this.props.history.push({
    pathname:'/user',state:{
    day : 'Friday' } }) this.props.location.state.day

    (6) 路由拦截

    const check = ()=>{
    return localStorage.getItem("token")}{
    /* 路由拦截 */}{
    /* check 有token跳到center 没有token 重定向login */}
    check()?
    :
    }/>

    (7) withRouter的应用与原理

    function CinemaHeader (props) {  return (    
    )}export default function Cinema () { return (
    )}

    props 打印{},因为 CinemaHeader的父组件(Cinema) 没有给他传属性,只有Route组件才有props属性。

    解决方案有:

    1. 在父组件自己写一个属性传给子组件CinemaHeader,属性里面写一个回调函数,子组件调用回调函数
    export default function Cinema (props) {  return (    
    { console.log("leftclick"); props.history.push('/cinema/search') }}>
    )} function CinemaHeader (props) { return (
    )}
    1. {…props}
    // 父组件把Route传过来的props展开传给子组件,子组件就可以用props.historyexport default function Cinema (props) {  return (    
    )} function CinemaHeader (props) { return (
    )}
    1. withRouter
    import {withRouter} from 'react-router-dom' // 导入 withRouter function CinemaHeader(props) {    return (        
    )}export default withRouter(CinemaHeader) // withRouter 包裹子组件

    原理:利用高阶组件封装出来的一个组件

    /* withRouter 高阶函数 高阶组件 (High-order-component)  ==  HOC  (输入低阶组件, 得到高阶组件)*/ function withRouter(MyComponent){
    ..... ..... return function(){
    return
    } }/* function add(a,b){ return a+b}function AAA(add){ return function(a,b){ return add(a*a,b*b) }}// var result = add(1,2)// console.log(result)var advancedAdd = AAA(add)console.log(advancedAdd(1,2)) */

    自己封装高阶组件(复用思想)

    import React,{
    useEffect} from 'react'function withCenter(MyComponent){
    return function(){
    useEffect(() => {
    window.onresize = ()=>{
    console.log("resize") } }, []) return
    }} function Center(props) {
    console.log(props) return (
    center
    )}export default withCenter(Center)

    history模式

    BrowserRouter 没有#,后端找不到会报404

    // 配置路由的文件import React from 'react'import {
    BrowserRouter, Route, Switch } from 'react-router-dom'import Film from '../views/Film'import Login from '../views/Login'export default function MyRouter (props) {
    return (
    )}

    cssmodule

    css样式 会全局影响,react没有scope ,需要把css 文件改为 filename.module.css

    //导入import style from './Film.module.css'// 用的时候通过style.样式名
    film-header

    转载地址:http://pqyrf.baihongyu.com/

    你可能感兴趣的文章
    hibernate 时间段查询
    查看>>
    java操作cookie 实现两周内自动登录
    查看>>
    Tomcat 7优化前及优化后的性能对比
    查看>>
    Java Guava中的函数式编程讲解
    查看>>
    Eclipse Memory Analyzer 使用技巧
    查看>>
    tomcat连接超时
    查看>>
    谈谈编程思想
    查看>>
    iOS MapKit导航及地理转码辅助类
    查看>>
    检测iOS的网络可用性并打开网络设置
    查看>>
    简单封装FMDB操作sqlite的模板
    查看>>
    iOS开发中Instruments的用法
    查看>>
    iOS常用宏定义
    查看>>
    什么是ActiveRecord
    查看>>
    有道词典for mac在Mac OS X 10.9不能取词
    查看>>
    关于“团队建设”的反思
    查看>>
    利用jekyll在github中搭建博客
    查看>>
    Windows7中IIS简单安装与配置(详细图解)
    查看>>
    linux基本命令
    查看>>
    BlockQueue 生产消费 不需要判断阻塞唤醒条件
    查看>>
    强引用 软引用 弱引用 虚引用
    查看>>