45、React 路由:基础与高级特性详解

React 路由:基础与高级特性详解

1. URL 路由基础

URL 路由是一种通过操作浏览器的 URL 来实现导航的技术,它无需向服务器发送 HTTP 请求。在 Web 应用中,核心的路由功能通常由 BrowserRouter HashRouter 组件提供。

1.1 选择和配置路由组件

在导入时,这两个组件通常被命名为 Router ,示例代码如下:

import { BrowserRouter as Router, Link, Switch, Route, Redirect }
    from "react-router-dom";
1.2 BrowserRouter 组件

BrowserRouter 使用 HTML5 History API,能提供自然的路由 URL,例如 http://localhost:3000/products 。该组件可以接受一系列的属性来配置其行为,详细属性如下表所示:
| 属性名 | 描述 |
| ---- | ---- |
| basename | 当应用程序不在其 URL 的根目录时使用,例如 http://localhost:3000/myapp |
| getUserConfirmation | 用于指定获取用户对导航确认的函数,与 Prompt 组件配合使用 |
| forceRefresh | 当值为 true 时,导航时会强制进行完全刷新并向服务器发送 HTTP 请求,通常仅用于测试或浏览器不支持 History API 的情况 |
| keyLength | 每次导航更改都会有一个唯一的键,此属性用于指定键的长度,默认值为 6 个字符 |
| history | 允许使用自定义的历史对象 |

1.3 HashRouter 组件

对于不支持 History API 的旧浏览器,导航信息需要作为 URL 片段添加到 URL 末尾,即 # 字符之后。 HashRouter 组件提供了基于 URL 片段的路由功能,使用示例如下:

import React, { Component } from "react";
import { HashRouter as Router, NavLink, Route, Switch, Redirect }
    from "react-router-dom";
import { ProductDisplay } from "./ProductDisplay";
import { SupplierDisplay } from "./SupplierDisplay";
export class Selector extends Component {
    // ...methods omitted for brevity...
}

使用 as 关键字导入路由组件,只需更改导入语句。保存文件更改后,导航到 http://localhost:3000 ,可以看到 URL 样式发生了变化。 HashRouter 组件也可以通过一些属性进行配置,具体如下表:
| 属性名 | 描述 |
| ---- | ---- |
| basename | 当应用程序不在其 URL 的根目录时使用,例如 http://localhost:3000/myapp |
| getUserConfirmation | 用于指定获取用户对导航确认的函数,与 Prompt 组件配合使用 |
| hashType | 设置 URL 中路由编码的样式,可选值有 slash noslash hashbang |

2. 高级 URL 路由特性

高级 URL 路由特性为 React 应用提供了更强大的路由控制能力,下面详细介绍这些特性。

2.1 准备工作

在使用高级路由特性之前,需要将应用程序使用的路由器从 HashRouter 更改为 BrowserRouter ,并简化 Link Router 组件,示例代码如下:

import React, { Component } from "react";
import { BrowserRouter as Router, NavLink, Route, Switch, Redirect }
    from "react-router-dom";
import { ProductDisplay } from "./ProductDisplay";
import { SupplierDisplay } from "./SupplierDisplay";
export class Selector extends Component {
    render() {
        return <Router>
            <div className="container-fluid">
                <div className="row">
                    <div className="col-2">
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active"
                            to="/products">Products</NavLink>
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active"
                            to="/suppliers">Suppliers</NavLink>
                    </div>
                    <div className="col">
                        <Switch>
                            <Route path="/products" component={ ProductDisplay} />
                            <Route path="/suppliers" component={ SupplierDisplay } />
                            <Redirect to="/products" />
                        </Switch>
                    </div>
                </div>
            </div>
        </Router>
    }
}

完成上述更改后,在命令提示符中导航到项目文件夹,并运行以下命令启动开发工具:

npm start
2.2 创建路由感知组件

Route 组件显示一个组件时,会为其提供描述当前路由的上下文数据以及用于导航的 API,使组件能够感知当前位置并参与路由。当使用 component 属性时, Route 会将数据和 API 作为 match location history 属性传递给显示的组件;当使用 render 属性时,渲染函数会接收到一个包含 match location history 属性的对象。这些对象的详细描述如下表所示:
| 属性名 | 描述 |
| ---- | ---- |
| match | 提供 Route 组件如何匹配当前浏览器 URL 的信息 |
| location | 提供当前位置的表示,可用于导航而无需使用字符串形式的 URL |
| history | 提供用于导航的 API |

2.3 理解 match 属性

match 属性为组件提供了父 Route 如何匹配当前 URL 的详细信息。其包含的属性如下表所示:
| 属性名 | 描述 |
| ---- | ---- |
| url | 返回 Route 匹配的 URL |
| path | 返回用于匹配 URL 的路径值 |
| params | 返回路由参数,允许将 URL 段映射到变量 |
| isExact | 如果路由路径与 URL 完全匹配,则返回 true |

为了演示路由属性的使用,创建了一个 RouteInfo 组件,代码如下:

import React, { Component } from "react";
export class RouteInfo extends Component {
    renderTable(title, prop, propertyNames) {
        return <React.Fragment>
            <tr><th colSpan="2" className="text-center">{ title }</th></tr>
            { propertyNames.map(p =>
                <tr key={p }>
                    <td>{ p }</td>
                    <td>{ JSON.stringify(prop[p]) }</td>
                </tr>)
            }
        </React.Fragment>
    }
    render() {
        return <div className="bg-info m-2 p-2">
            <h4 className="text-white text-center">Route Info</h4>
            <table className="table table-sm table-striped bg-light">
                <tbody>
                    { this.renderTable("Match", this.props.match,
                        ["url", "path", "params", "isExact"] )}
                </tbody>
            </table>
        </div>
    }
}

Selector 组件中添加导航链接和对应的 Route ,代码如下:

import React, { Component } from "react";
import { BrowserRouter as Router, NavLink, Route, Switch, Redirect }
    from "react-router-dom";
import { ProductDisplay } from "./ProductDisplay";
import { SupplierDisplay } from "./SupplierDisplay";
import { RouteInfo } from "./routing/RouteInfo";
export class Selector extends Component {
    render() {
        return <Router>
            <div className="container-fluid">
                <div className="row">
                    <div className="col-2">
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active"
                            to="/products">Products</NavLink>
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active"
                            to="/suppliers">Suppliers</NavLink>
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active" to="/info">Route Info</NavLink>
                    </div>
                    <div className="col">
                        <Switch>
                            <Route path="/products" component={ ProductDisplay} />
                            <Route path="/suppliers" component={ SupplierDisplay } />
                            <Route path="/info" component={ RouteInfo } />
                            <Redirect to="/products" />
                        </Switch>
                    </div>
                </div>
            </div>
        </Router>
    }
}

保存更改后,点击 Route Info 链接,即可看到 match 属性的详细信息。

2.4 理解 location 属性

location 对象用于描述导航位置,作为属性提供时,它描述了当前位置。其包含的属性如下表所示:
| 属性名 | 描述 |
| ---- | ---- |
| key | 返回标识位置的键 |
| pathname | 返回位置的路径 |
| search | 返回位置 URL 的搜索项(即 URL 中 ? 字符后面的部分) |
| hash | 返回位置 URL 的 URL 片段(即 # 字符后面的部分) |
| state | 用于将任意数据与位置关联 |

RouteInfo 组件中添加 location 属性的显示,并使用 location 对象作为 Link 组件的导航目标,代码如下:

import React, { Component } from "react";
import { Link } from "react-router-dom";
export class RouteInfo extends Component {
    renderTable(title, prop, propertyNames) {
        return <React.Fragment>
            <tr><th colSpan="2" className="text-center">{ title }</th></tr>
            { propertyNames.map(p =>
                <tr key={p }>
                    <td>{ p }</td>
                    <td>{ JSON.stringify(prop[p]) }</td>
                </tr>)
            }
        </React.Fragment>
    }
    render() {
        return <div className="bg-info m-2 p-2">
            <h4 className="text-white text-center">Route Info</h4>
            <table className="table table-sm table-striped bg-light">
                <tbody>
                    { this.renderTable("Match", this.props.match,
                        ["url", "path", "params", "isExact"] )}
                    { this.renderTable("Location", this.props.location,
                        ["key", "pathname", "search", "hash", "state"] )}
                </tbody>
            </table>
            <div className="text-center m-2 bg-light">
                <Link className="btn btn-primary m-2"
                    to={ this.props.location }>Location</Link>
            </div>
        </div>
    }
}
2.5 使用 URL 参数

当组件感知到 URL 路由系统时,通常需要根据当前 URL 调整其行为。React-Router 包支持 URL 参数,允许将 URL 段的内容分配给变量,组件可以读取这些变量而无需解析 URL 或了解其结构。以下是添加包含 URL 参数的 Route 和目标 Link 组件的示例代码:

import React, { Component } from "react";
import { BrowserRouter as Router, NavLink, Route, Switch, Redirect }
    from "react-router-dom";
import { ProductDisplay } from "./ProductDisplay";
import { SupplierDisplay } from "./SupplierDisplay";
import { RouteInfo } from "./routing/RouteInfo";
export class Selector extends Component {
    render() {
        return <Router>
            <div className="container-fluid">
                <div className="row">
                    <div className="col-2">
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active"
                            to="/products">Products</NavLink>
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active"
                            to="/suppliers">Suppliers</NavLink>
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active"
                            to="/info/match">Match</NavLink>
                        <NavLink className="m-2 btn btn-block btn-primary"
                            activeClassName="active"
                            to="/info/location">Location</NavLink>
                    </div>
                    <div className="col">
                        <Switch>
                            <Route path="/products" component={ ProductDisplay} />
                            <Route path="/suppliers" component={ SupplierDisplay } />
                            <Route path="/info/:datatype" component={ RouteInfo } />
                            <Redirect to="/products" />
                        </Switch>
                    </div>
                </div>
            </div>
        </Router>
    }
}

URL 参数通过在路径属性段前加冒号( : )来指定。当 Route 匹配 URL 时,会将相应的 URL 段值分配给参数,并通过 match 属性的 params 属性传递给组件。

更新 RouteInfo 组件以使用 URL 参数选择要呈现给用户的上下文数据,代码如下:

import React, { Component } from "react";
import { Link } from "react-router-dom";
export class RouteInfo extends Component {
    renderTable(title, prop, propertyNames) {
        return <React.Fragment>
            <tr><th colSpan="2" className="text-center">{ title }</th></tr>
            { propertyNames.map(p =>
                <tr key={p }>
                    <td>{ p }</td>
                    <td>{ JSON.stringify(prop[p]) }</td>
                </tr>)
            }
        </React.Fragment>
    }
    render() {
        return <div className="bg-info m-2 p-2">
            <h4 className="text-white text-center">Route Info</h4>
            <table className="table table-sm table-striped bg-light">
                <tbody>
                    { this.props.match.params.datatype ==="match"
                        && this.renderTable("Match", this.props.match,
                            ["url", "path", "params", "isExact"] )}
                    { this.props.match.params.datatype === "location"
                        &&  this.renderTable("Location", this.props.location,
                            ["key", "pathname", "search", "hash", "state"] )}
                </tbody>
            </table>
            <div className="text-center m-2 bg-light">
                <Link className="btn btn-primary m-2"
                    to={ this.props.location }>Location</Link>
            </div>
        </div>
    }
}

URL 参数不仅是组件接收 URL 段内容的便捷方式,还能将 URL 的结构与目标组件解耦,允许更改 URL 结构或使用多个 URL 指向相同内容而无需修改组件代码。组件只需知道所需的 URL 参数名称,而无需了解它们在 URL 中的具体位置。

2.6 URL 参数的优势及应用场景

URL 参数具有显著的优势,其不仅是组件接收 URL 段内容的便捷途径,还能将 URL 的结构与目标组件进行解耦。这意味着可以对 URL 的结构进行修改,或者让多个 URL 指向相同的内容,而无需对组件代码进行修改。

以下是 URL 参数的优势及应用场景的详细说明:
- 解耦 URL 结构与组件 :组件只需关注所需的 URL 参数名称,而无需了解这些参数在 URL 中的具体位置。例如,在前面的 RouteInfo 组件中,它依赖于 datatype URL 参数,但并不依赖于该参数在 URL 中的具体位置。这使得组件可以适配不同的路径,如 /info/:datatype /diagnostics/routing/:datatype ,而无需修改代码。
- 多 URL 指向相同内容 :可以使用多个不同的 URL 来访问相同的内容,而无需修改组件。例如,可以同时使用 /info/match /diagnostics/routing/match 来访问相同的信息,只需确保 URL 参数名称一致即可。
- 简化组件逻辑 :组件可以直接通过 URL 参数获取所需的数据,而无需解析整个 URL。这简化了组件的逻辑,提高了代码的可读性和可维护性。

2.7 高级路由特性的总结

高级 URL 路由特性为 React 应用提供了更强大的路由控制能力,使组件能够更好地感知和参与路由过程。以下是对这些特性的总结:
| 特性 | 描述 |
| ---- | ---- |
| 创建路由感知组件 | 通过 Route 组件提供的 match location history 属性,组件可以感知当前路由信息并参与导航 |
| 理解 match 属性 | match 属性提供了 Route 组件如何匹配当前 URL 的详细信息,包括匹配的 URL、路径、参数和是否完全匹配等 |
| 理解 location 属性 | location 对象描述了当前导航位置,包括键、路径名、搜索项、哈希值和关联的数据等 |
| 使用 URL 参数 | URL 参数允许将 URL 段的内容分配给变量,组件可以直接读取这些变量,而无需解析 URL 或了解其结构 |

3. 路由的实际应用与流程

3.1 路由配置流程

在实际应用中,配置路由通常遵循以下步骤:
1. 导入路由组件 :从 react-router-dom 中导入所需的路由组件,如 BrowserRouter NavLink Route Switch Redirect
2. 定义路由结构 :在组件中定义路由的结构,包括导航链接和对应的路由规则。
3. 配置路由参数 :如果需要使用 URL 参数,在路由路径中添加参数,并在组件中使用这些参数。
4. 渲染路由组件 :将路由组件渲染到应用中,确保路由功能正常工作。

以下是一个完整的路由配置示例:

import React, { Component } from "react";
import { BrowserRouter as Router, NavLink, Route, Switch, Redirect }
    from "react-router-dom";
import { ProductDisplay } from "./ProductDisplay";
import { SupplierDisplay } from "./SupplierDisplay";
import { RouteInfo } from "./routing/RouteInfo";

export class Selector extends Component {
    render() {
        return (
            <Router>
                <div className="container-fluid">
                    <div className="row">
                        <div className="col-2">
                            <NavLink className="m-2 btn btn-block btn-primary"
                                activeClassName="active"
                                to="/products">Products</NavLink>
                            <NavLink className="m-2 btn btn-block btn-primary"
                                activeClassName="active"
                                to="/suppliers">Suppliers</NavLink>
                            <NavLink className="m-2 btn btn-block btn-primary"
                                activeClassName="active"
                                to="/info/match">Match</NavLink>
                            <NavLink className="m-2 btn btn-block btn-primary"
                                activeClassName="active"
                                to="/info/location">Location</NavLink>
                        </div>
                        <div className="col">
                            <Switch>
                                <Route path="/products" component={ProductDisplay} />
                                <Route path="/suppliers" component={SupplierDisplay} />
                                <Route path="/info/:datatype" component={RouteInfo} />
                                <Redirect to="/products" />
                            </Switch>
                        </div>
                    </div>
                </div>
            </Router>
        );
    }
}
3.2 路由导航流程

当用户进行导航时,路由系统会按照以下流程进行处理:

graph TD;
    A[用户点击导航链接] --> B[路由系统捕获 URL 变化];
    B --> C[根据路由规则匹配 URL];
    C --> D{是否匹配成功};
    D -- 是 --> E[渲染对应的组件];
    D -- 否 --> F[执行重定向或显示错误信息];

具体步骤如下:
1. 用户点击导航链接 :用户在应用中点击导航链接,触发 URL 的变化。
2. 路由系统捕获 URL 变化 :路由系统会监测到 URL 的变化,并开始处理导航请求。
3. 根据路由规则匹配 URL :路由系统会根据预先定义的路由规则,尝试匹配当前的 URL。
4. 判断是否匹配成功 :如果匹配成功,路由系统会渲染对应的组件;如果匹配失败,会执行重定向或显示错误信息。
5. 渲染组件或执行重定向 :如果匹配成功,路由系统会将对应的组件渲染到页面上;如果匹配失败,会根据重定向规则跳转到指定的页面。

4. 总结

通过本文的介绍,我们了解了 React 中 URL 路由的基础和高级特性。基础部分介绍了 BrowserRouter HashRouter 组件的使用和配置,以及如何通过路由实现导航。高级部分则深入探讨了路由感知组件、 match location 属性、URL 参数等特性,使组件能够更好地感知和参与路由过程。

在实际应用中,合理使用这些路由特性可以提高应用的可维护性和用户体验。通过 URL 参数,可以将 URL 的结构与组件解耦,使组件更加灵活和可复用。同时,了解路由的配置和导航流程,可以帮助我们更好地设计和实现复杂的路由系统。

希望本文能够帮助你更好地理解和应用 React 中的 URL 路由,提升你的开发技能和应用质量。

基于径向基函数神经网络RBFNN的自适应滑模控制学习(Matlab代码实现)内容概要:本文介绍了基于径向基函数神经网络(RBFNN)的自适应滑模控制方法,并提供了相应的Matlab代码实现。该方法结合了RBF神经网络的非线性逼近能力和滑模控制的强鲁棒性,用于解决复杂系统的控制问题,尤其适用于存在不确定性和外部干扰的动态系统。文中详细阐述了控制算法的设计思路、RBFNN的结构权重更新机制、滑模面的构建以及自适应律的推导过程,并通过Matlab仿真验证了所提方法的有效性和稳定性。此外,文档还列举了大量相关的科研方向和技术应用,涵盖智能优化算法、机器学习、电力系统、路径规划等多个领域,展示了该技术的广泛应用前景。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的研究生、科研人员及工程技术人员,特别是从事智能控制、非线性系统控制及相关领域的研究人员; 使用场景及目标:①学习和掌握RBF神经网络滑模控制相结合的自适应控制策略设计方法;②应用于电机控制、机器人轨迹跟踪、电力电子系统等存在模型不确定性或外界扰动的实际控制系统中,提升控制精度鲁棒性; 阅读建议:建议读者结合提供的Matlab代码进行仿真实践,深入理解算法实现细节,同时可参考文中提及的相关技术方向拓展研究思路,注重理论分析仿真验证相结合。
先展示下效果 https://pan.quark.cn/s/a4b39357ea24 本项目是本人参加BAT等其他公司电话、现场面试之后总结出来的针对Java面试的知识点或真题,每个点或题目都是在面试中被问过的。 除开知识点,一定要准备好以下套路: 个人介绍,需要准备一个1分钟的介绍,包括学习经历、工作经历、项目经历、个人优势、一句话总结。 一定要自己背得滚瓜烂熟,张口就来 抽象概念,当面试官问你是如何理解多线程的时候,你要知道从定义、来源、实现、问题、优化、应用方面系统性地回答 项目强化,至少知识点的比例是五五开,所以必须针对简历中的两个以上的项目,形成包括【架构和实现细节】,【正常流程和异常流程的处理】,【难点+坑+复盘优化】三位一体的组合拳 压力练习,面试的时候难免紧张,可能会严重影响发挥,通过平时多找机会参交流分享,或找人做压力面试来改善 表达练习,表达能力非常影响在面试中的表现,能否简练地将答案告诉面试官,可以通过给自己讲解的方式刻意练习 重点针对,面试官会针对简历提问,所以请针对简历上写的所有技术点进行重点准备 Java基础 JVM原理 集合 多线程 IO 问题排查 Web框架、数据库 Spring MySQL Redis 通用基础 操作系统 网络通信协议 排序算法 常用设计模式 从URL到看到网页的过程 分布式 CAP理论 锁 事务 消息队列 协调器 ID生成方式 一致性hash 限流 微服务 微服务介绍 服务发现 API网关 服务容错保护 服务配置中心 算法 数组-快速排序-第k大个数 数组-对撞指针-最大蓄水 数组-滑动窗口-最小连续子数组 数组-归并排序-合并有序数组 数组-顺时针打印矩形 数组-24点游戏 链表-链表反转-链表相加 链表-...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值