现在用react写单页应用基本上都是用react-router做前端路由了吧!最近在使用react-router的过程中遇到了不少问题,在这里总结一下。

浏览器url

react-router默认提供的history是 createHashHistory ,即它用到的是 URL 中的 hash(#)部分去创建形如 example.com/#/some/path 的路由,所以你会看到url多了类似 _key=s1gvrm  的 query,这真的很难看。而且这也不是官方在实际生产应用中所推荐的。要改变这种情况的话,我们需要去使用 createBrowserHistory ,在我们的代码中引入history,并在Router组件处调用 createBrowserHistory  方法即可。

import React from "react";
import ReactDOM from "react-dom";
import createBrowserHistory from "history/lib/createBrowserHistory"
import { Router,Route,Link,browserHistory,IndexRoute,IndexLink } from "react-router"; class App extends React.Component{ render(){
return(
...
);
}
}; ReactDOM.render((
<Router history={ createBrowserHistory() }>
...
</Router>
),document.getElementById("app"));

其实关于url还有许多的细节,因为react-router本身就是构建于history之上的。单页应用的url只不过是针对于react- router的一个标示而已,界面间的跳转全然由react-router决定,react-router检查当前url随后渲染匹配的路由组件,因为是前端路由,所以如果直接在浏览器上输入相对应的组件url,而后端却不对此url做任何的匹配的话,可能会得到404响应。

组件通信

这是一个用react写代码永远都绕不开的话题。react-router是基于react开发的,所以它的每一个route都是一个组件。路由组件间的通信一般借由Link来实现,而根据路由参数的不同,还可以分成两种。这个很容易理解,因为这两种方式和我们平时写的后台路由并没有什么太大差别。

1 param,param通过/:param的方式传递。

比如说我们现在有一个显示消息列表的路由组件,我们需要在点击每一个消息的时候能跳转到显示被点击消息详情的路由组件。这个时候我们消息详情路由组件可以是这样定义的:

<Route path="News_detail/:news_id" component={ news_detail }/>

在消息列表路由组件那里我们让每一条消息都是这样的一个Link:

<Link to={ `News_detail/${ element.timestamp }` } >{ element.news }</Link>

这样的话我们的消息详情组件就能通过  this.props.params 获取到消息列表组件传递而来的  element.timestamp 参数了。

2 query

<Link to="/Activity_Publish" query={{ timestamp : element.timestamp }}>编辑</Link>

在  /Activity_Publish 映射的路由组件里面可以通过

var { query } = this.props.location;
var timestamp = query.timestamp;

获取到query参数。

相对于param,局限性更小,你可以根据需要传递更多的参数,只不过有点类似于get请求,传递的参数会附带在url后面,看起来有点丑,而且几乎无隐蔽性可言。

3 state

这种方式借助了location 对象,location 对象可以简单的认为是 url 的对象形式表示,这里要提的是 location.state,每个 URL 都会对应一个 state 对象,你可以在对象里存储数据,但这个数据却不会出现在 url 中。实际上,数据被存在了 sessionStorage 中,旧的路由组件可以借助这种方式传递数据给新的路由组件,但是会有个问题就是,新的路由组件虽然在首次被渲染的时候可以成功拿到数据,但是如果此时浏览器被刷新的话,传递过来的数据也会消失。

<Link to="/Activity_Publish" state={{ timestamp : element.timestamp }}>编辑</Link>

按需加载

react-router协同webpack的使用可以实现组件的按需加载,而且 这种按需加载完全是异步的,这点特别酷炫,你不再需要一口气加载那么大的js文件,即使里面包含着许多用户甚至都不会使用到的web组件。你可以只根据需 要加载用户浏览的那些组件,这个举措将会帮你大大的降低首屏渲染的时间。

实现这个功能很简单,比如在一开始你的路由是这样子的:

...
import News_detail from "./marriage_component/activity/news_detail.jsx";
... class App extends React.Component{ render(){
...
}
}; ReactDOM.render((
<Router history={ createBrowserHistory() }>
<Route path="/marriage_app" component={ App }>
...
<Route path="/marriage_app/News_detail/:news_id" component={ News_detail }/>
...

把它改成这样就行了:

...
//import News_detail from "./marriage_component/activity/news_detail.jsx";
... class App extends React.Component{ render(){
...
}
}; ReactDOM.render((
<Router history={ createBrowserHistory() }>
<Route path="/marriage_app" component={ App }>
...
<Route path="/marriage_app/News_detail/:news_id" getComponent={ (nextState, callback) =>{
require.ensure( [ ], (require) => {
callback(null, require("./marriage_component/activity/news_detail").default)
}) } }/>
...

一开始的组件不再需要被导入,webpack会帮你在需要的时候引入它。

最后

这种前后端分离的模式真的很赞,但似乎对SEO并不是很友好。如果真的需要SEO,又追求于实现前后端的真正解耦,是不是以Nodejs为中间层的架构模式会成为一种解决方案呢?

记、基于react-router的单页应用的更多相关文章

  1. 基于VUE的SPA单页应用开发-加载性能篇

    1.基于异步数据的vue页面刷新 先看看基于异步数据的vue页面刷新后,都发生了啥- 如图所示: 图1 基于异步数据的vue页面刷新 网络请求图 步骤如下: step1:请求页面: step2:请求页 ...

  2. 基于jQuery/zepto的单页应用(SPA)搭建方案

    这里介绍一个基于jquery或zepto的单页面应用方案,遵循尽可能简单的原则,使大家一目了然,只需配置一个路由,之后完全按照jq日常写法即可完成.可做学习使用,也可修改后用于一些业务逻辑简单的spa ...

  3. vue学习之用 Vue.js + Vue Router 创建单页应用的几个步骤

    通过vue学习一:新建或打开vue项目,创建好项目后,接下来的操作为: src目录重新规划——>新建几个页面——>配置这几个页面的路由——>给根实例注入路由配置 src目录重整 在项 ...

  4. React构建单页应用方法与实例

    React作为目前最流行的前端框架之一,其受欢迎程度不容小觑,从这门框架上我们可以学到许多其他前端框架所缺失的东西,也是其创新性所在的地方,比如虚拟DOM.JSX等.那么接下来我们就来学习一下这门框架 ...

  5. 单页应用后退不刷新方案(vue & react)

    引言 前进刷新,后退不刷新,是一个类似app页面的特点,要在单页web应用中做后退不刷新,却并非一件易事. 为什么麻烦 spa的渲染原理(以vue为例):url的更改触发onHashChange/pu ...

  6. 基于React和Node.JS的表单录入系统的设计与实现

    一.写在前面 这是一个真实的项目,项目已经过去好久了,虽然很简单,但还是有很多思考点,跟随着笔者的脚步,一起来看看吧.本文纯属虚构,涉及到的相关信息均已做虚构处理, 二.背景 人活着一定要有信仰,没有 ...

  7. 基于Vue2.0+Vue-router构建一个简单的单页应用

    爱编程爱分享,原创文章,转载请注明出处,谢谢!http://www.cnblogs.com/fozero/p/6185492.html 一.介绍 vue.js 是 目前 最火的前端框架,vue.js ...

  8. Node.js + React + MongoDB 实现 TodoList 单页应用

    之前用 Ant Design 开发了一个项目,因此对 React 的特性有了一定的了解,React 使用封装组件的思想,组件各自维护自己的状态和 UI, 组件之间通过 props 传递数据和方法.当状 ...

  9. React + Node 单页应用「二」OAuth 2.0 授权认证 & GitHub 授权实践

    关于项目 项目地址 预览地址 记录最近做的一个 demo,前端使用 React,用 React Router 实现前端路由,Koa 2 搭建 API Server, 最后通过 Nginx 做请求转发. ...

随机推荐

  1. iOS基于MBProgressHUD的二次封装,一行搞定,使用超简单

    MBProgressHUD的使用,临时总结了几款最常用的使用场景: 1.提示消息 用法: [YJProgressHUD showMessage:@"显示文字,1s隐藏" inVie ...

  2. day 2 系统分区 扩展.md

    1.分区类型 主分区: 最多只能有四个. 扩展分区: 最多只能有一个. 主分区加扩展分区最多有4个. 不能写入数据,只能包含逻辑分区. 逻辑分区 2.格式化 格式化(高级格式化)又称逻辑格式化,它是指 ...

  3. django自动化部署脚本

    while read line;do echo'kill '$line; kill $line; done < /tmp/celeryd.pid while read line;do echo' ...

  4. 使用Apache2配置多个站点

      六 27 pache2主配置文件: /etc/apache2/apache2.conf.其最后两行为: # Include the virtual host configurations:Incl ...

  5. ELF Format 笔记(三)—— Section Types

    ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 ELF 文件中会包含很多 section,所有的 section 都在 section header tab ...

  6. high三个晚上这样好么-JSON&PHP

    hi 昨晚上吃火锅去了,对,你没猜错,我就是在成都 今晚有师兄请客,明天有基友请吃火锅,本来该忙忙哒的这一周要连续high三个晚上么(单身研究生狗就是这么容易满足).所以只好不务正业写写写了(写不动了 ...

  7. APDU

    # APDU # 定义:APDU(ApplicationProtocolDataUnit--应用协议数据单元).协议数据单元PDU(ProtocolDataUnit)是指对等层次之间传递的数据单位.协 ...

  8. 使用xpath时出现noDefClass的错误(找不到某个类)

    今天继续封装下jdom 发现jdom引用了个jaxen的jar 如果不导入这个库,使用xpath时出现noDefClass的错误(找不到某个类) 到csdn上 下了个 ok 同时研究了下List的to ...

  9. javascript高级程序设计 读书笔记1

    第二章  在HTML中使用JS 加载JS有三种:行内,head头部和外部链接JS   最好使用外部链接<script src="example.js" ></sc ...

  10. [No000001]一切都是最好的安排

    <一切都是最好的安排> 从前有一个国家,地不大,人不多,但是人民过着悠闲快乐的生活,因为他们有一位不喜欢做事的国王和一位不喜欢做官的宰相. 国王没有什么不良嗜好,除了打猎以外,最喜欢与宰相 ...