现在用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. 0005 《SQL必知必会》笔记01-SELECT语句

    1.SELECT基本语句: SELECT 字段名1,···,字段名n FROM 表名 2.检索所有字段,用"*"替换字段名,这会导致效率低下 SELECT * FROM 表名; 3 ...

  2. Linux下NDK编译FFMPEG包含neon参数

    FFMPEG编译成Android库已经有很多案例了,编译优化neon的也很多,以下是我通过实践成功的案例,这里主要讲编译的配置文件,其他设置可结合Linux下使用NDK编译FFMPEG(libstag ...

  3. nodeJS Express 删除 x-powered-by

    在使用Express4 Header头部会输出,在晚上搜索几种方案也没有产生效果,就看了一下官方文档 Property Type               Value Default     x-p ...

  4. shell流程控制

    if语句 判断条件用[]包裹起来 if [ $a > $b ] then echo ‘a > b’ elif [ $a < $b ] then echo ‘a < b’ els ...

  5. 报表引擎API开发入门—带参程序数据集

    我们今天又来讲讲报表开发的事,上周开的这个系列入门文章也三四天了,浏览量不佳小编甚是悲伤啊,希望大家多多支持我! 一.问题描述 在实际应用中,可能需要根据表名动态地改变数据源,比如在程序数据集中,通过 ...

  6. web报表工具FineReport常用函数的用法总结(报表函数)

    说明:本次总结中,凡是以tableName或viewName作为参数因子的.函数在调用的时候均按照先从私有数据源中查找,然后再从公有数据源中查找的顺序. CLASS CLASS(object):返回o ...

  7. Azure Linux VM Swap 分区

    默认情况下,Windows Azure上的Linux VM是没有Swap分区的.下面我们以Ubuntu为例,为Windows Azure上的Linux虚拟机创建Swap分区. Windows Azur ...

  8. Superpixel Based RGB-D Image Segmentation Using Markov Random Field——阅读笔记

    1.基本信息 题目:使用马尔科夫场实现基于超像素的RGB-D图像分割: 作者所属:Ferdowsi University of Mashhad(Iron) 发表:2015 International ...

  9. MMORPG大型游戏设计与开发(客户端架构 part2 of vgui)

    这一节我将讲解vgui的基础系统部分,也是该库提供给外部使用的一些重要接口.作为UI部分比较重要的部分,该节有着至关重要的部分,如果没有看到上一节内容,请留意下面的连接.我们现在可以猜想一下在客户端U ...

  10. Java方法区和运行时常量池溢出问题分析

    运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名.访问修饰符.常量池.字段描述.方法描述等. String.intern()是一个native方法,它的作用是:如果字符串常量池 ...