现在用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. fopen()、 file_get_contents() 通过url获取链接内容

    功能:获得网页内容 区别如下: fopen()打开URL 下面是一个使用fopen()打开URL的例子: <?php $fh = fopen('http://www.baidu.com/', ' ...

  2. 0016 Java学习笔记-异常-如果try-catch-finally中都存在return语句会怎样?

    上午在搜索"System.runFinalization"的时候,搜到 http://www.cnblogs.com/Skyar/p/5962253.html ,其中有关于try- ...

  3. IE下innerText与FoxFire下textContent属性的不同

    <div> 我是中国 人 我<br/>爱 自己 的<div>祖国</div>. <div> IE下输出 我是中国 人 我 爱 自己 的 祖国 ...

  4. iOS 实现Tabbarcontroller中间自定义样式 最简单的方法

    先上图: 如果我们要实现中间按钮自定义样式,方法应该蛮多,这里介绍一种最简单的. 1.创建类继承:UITabBarController,如下代码都是写在该类的 .m文件里 2.定义最中间的自定义样式, ...

  5. android 获取本机SMI卡号码

    //获取手机号码 TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); S ...

  6. PS色调均化滤镜的快捷实现(C#源代码)。

    photoshop色调均化功能通常是在进行修片处理前期比较常用的功能之一,其对扩展图像的对比度,增强视觉效果有一定的作用.在很多课本或者文章中,也称这种处理为灰度均衡化.直方图均衡化等等.算法原理都是 ...

  7. cuda并行计算的几种模式

    #include "cuda_runtime.h" #include "device_launch_parameters.h" #include <std ...

  8. POJ1849Two[DP|树的直径](扩展HDU4003待办)

    Two Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1390   Accepted: 701 Description Th ...

  9. 模版(template)

    模版(template) 在c++Template中很多地方都用到了typename与class这两个关键字,而且好像可以替换,是不是这两个关键字完全一样呢? 相信学习C++的人对class这个关键字 ...

  10. [No000052]大蒜怎么吃最美容?吃大蒜的功效及禁忌

    大蒜是最常见的香辛调味料,它被称为天然抗生素,富含大蒜素等多种营养物质和抗氧化剂,具有多种美肤美容作用. 大蒜的5种美容功效 1.除皱.大蒜里的某些成分,有类似维生素E与维生素C的抗氧化.防衰老特性, ...