通常,当用户在浏览器中键入 URL 时,会向服务器发送 HTTP 请求,然后服务器检索 html 页面。对于每个新URL,用户会被重定向到新的 html 页面。你可以通过参考下图来更好地理解路由的工作原理。
将单页应用限制为单一视图并不适用于 Facebook、Instagram 等流行的社交媒体网站,这些网站现在使用 React 呈现多个视图。我们需要继续前进,学习如何在单页面应用中显示多个视图。
例如我们习惯看到显示欢迎消息和相关内容的主页。网站介绍的详细信息可以在“关于我们”页面上找到,用户列表及其详细信息会出现在不同的页面上,可能还有其他各种页面包含很多不同的视图。
那么你认为这是怎样实现的呢? 在程序中添加路由器可以解决这一需求。
这将把我们带到本文的主题:React Router v4。 2017年3月13日,Micheal Jackson 和 Ryan Florence 发布了React Router v4 及可靠的文档。
他们相信“Learn Once, Route Anywhere”的理念。
在 React Conf 2017 的演讲中,他们通过展示如何将路由概念无缝地从 Web 平台投射到 Native 平台,以及将 React Router 集成到 VR 并在 React Native 中创建动画来解释这一点。虽然他们的谈话中的着眼点是围绕路由器 API 是如何“All About Components”的。
在React中,只涉及单个 “Html” 文件。每当用户输入新的 URL 请求时,路由不会从服务器获取数据,而是为每个新的 URL 请求交换不同的 Component。用户看上去是在多个页面之间进行切换,但实际上,根据我们的需要实现了多个视图,每个单独的组件被重新渲染。
React 是如何实现这一目标的?
这就是'History'的概念出现在图片中的地方。在 React 中,路由查看每个组件的历史记录,当历史记录发生任何变化时,组件会重新渲染。在 Router v4 之前,我们必须手动设置 History 的值。但是,从Router v4开始,<BrowserRouter>绕过了基本路径,为我们减少了大量的工作。如果你仍然需要访问历史记录,HTML5 提供了一个内置的 API,允许我们通过 pushState 和 replaceState 方法修改 History 对象。
实际上,React Router 4 完全重写了之前的版本。创建自己的路由只是你已经精通的 React Components 后的自然扩展。虽然学习它需要花费一些时间,但是一旦你继续前进,Router v4 将变得更有意义。
本质上我们是想在 React 的 render 方法中调用 Router Component。这是因为整个 Router API 都是关于组件的。当然,每个 Component 的角色都是像所有 React 应用一样呈现UI。
我们只需将自己的 Router App Component 包装在 <BrowserRouter> 中。
ReactDOM.render((
<BrowserRouter>
<App/>
</BrowserRouter>
), document.getElementById(“root”));
现在让我们通过一个例子来理解路由:
我们将创建三个页面。这是页面列表及其对应的地址。
Page | Address |
---|---|
Home | ‘/’ |
About | ‘/about’ |
Topic | ‘/topic’ |
react-router 库现在被分为三个独立的包。
我们需要安装依赖项:
$ npm install --save react-router-dom
(如果你没有安装最新的npm(5.x)版本,请使用 save 命令。)
从 react-router-dom 库中导入 BrowserRouter 以及 Link 和 Route。
可以将 BrowserRouter 可视化为呈现子路径的根组件。
import {
BrowserRouter,
Route,
Link
} from 'react-router-dom'
接下来让我们了解 Link 和 Route 组件,然后再继续了解 Router v4 的优势。
Link 用于在程序中的内部路由之间导航。它相当于锚标签:<a> </a>。
Link 传递一个字符串参数 to,其中指定了 URL 的路径。
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
现在看一下 <Route>,它可以被视为负责重新渲染 UI 的单一子组件。如果用户指定的位置与 <Route> 中定义的路径匹配,则 <Route> 可以通过两种方式定义视图:
如果指定的URL与定义的路径不匹配,<Route> 将返回 null。 <Route> 有两个参数,一个用于路径,另一个用于渲染 UI。
<BrowserRouter>
<div>
<Route exact path="/" render={ ( ) => (<h2> HomePage </h2>) } />
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</BrowserRouter>
无需使用 IndexRoute 呈现 HomePage,你会注意到前面代码片段中的 exact 属性。这是 React Router v4 声明 性质的一个的例子。
v4 中的路由为 inclusive 意味着可以同时呈现多个路由。我们使用 exact 属性来解决多匹配中的问题。
在前面的例子中没有使用 exact,URL '/' 将匹配路径 '/'、'/about' 和 '/topics'。但是我们希望 '/' 仅匹配我们的渲染函数,因此使用 exact 明确地实现了这一点。
这就是我们需要在 <div> 中包装路由的原因。如果不这样做,你会得到以下异常。
Uncaught Error: A <Router> may have only one child element
虽然我们可以在一个 <div> 标签中封装几个路由。如果我们希望一次只渲染一个路径组件,可以使用 <switch> 标签。它按顺序检查每个路径的匹配并在找到第一个匹配后停止。
<switch>
<route exact path=’/’ component={Home}/>
<route path=’/users/:id’ component={User }/>
<route path=’/users’ component={Roster}/>
<switch>
在示例中,我们将路径 /users/:id 放置在 /users 前面。这是因为 users/:id 将匹配 /users 和 /users/:id。
现在你已经对 React Router 有了基本的了解,下面是定义我们的 Router App Component 的完整代码。
const App= () => (
<BrowserRouter>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<Route exact path="/" render={ ( ) => (<h2> HomePage </h2>) } />
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</BrowserRouter>
)
React Router 再 v3 版本之前 是有 onEnter 钩子函数的,也支持静态路由配置;,但到了 v4 版本后钩子函数被移除,官方说是为了将此提供给开发者,由开发者自由发挥。既然如此我们就只能自己实现
目前前端三杰 Angular、React、Vue 都推介单页面应用 SPA 开发模式,在路由切换时替换 DOM Tree 中最小修改的部分 DOM,来减少原先因为多页应用的页面跳转带来的巨量性能损耗。它们都有自己的典型路由解决方案,@angular/router、react-router、vue-router
最近在研究权限的相关东西,自然动态加载路由信息少不了。接下来我就来专门记录下我研究的东西。先后端代码返回一个对象,用java写的,返回的是对象,不是字符,如果是字符前端注意转换成对象。
$router : 是路由操作对象,只写对象,$route : 路由信息对象,只读对象,path 和 Name路由跳转方式,都可以用query传参;path路由跳转方式,params传参会被忽略,只能用name命名的方式跳转
在使用react-router时会遇到奇怪的问题,比如当我们从首页进入详情页的时候,首页跳转到详情页,首页滚动的位置,进入到详情页的时候也会被记录下来,原因是由于共享了同一个history,所以对记录有所保留,这显然不符合我们的浏览习惯。
本文启发自实际项目中,随着项目不断增长,页面越来越多,不得不把vue-router的路由管理化繁为简、逐渐自动化的一个过程,希望能引发大家的思考;
从第一个页面跳转到第二个页面后,如果停留在第二个页面,定时器还在运行。如果在两个页面之间来回跳转,跳转时间小于定时器的间隔时间时,也会出现重复创建setTimeout的情况。
在有正在编辑的内容未保存时,发生了路由切换,此时需要给出一些提示,并由用户控制是否进行跳转。在react-router进行路由管理时,可以使用 Prompt 组件实现此功能
如果要你实现一个前端路由,应该如何实现浏览器的前进与后退 ?首先浏览器中主要有这几个限制,让前端不能随意的操作浏览器的浏览纪录:没有提供监听前进后退的事件。
在传统网站开发中,我们一般使用比如asp、php、jsp等技术进行开发,开发完成后统一部署在服务器上,我们访问时,会在浏览器中发送带有.asp,.php,.jsp等后缀路径的url请求,服务器会根据对应的路由映射表
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!