React 同构

搬运

https://segmentfault.com/a/1190000004671209

究竟什么是同构呢?

同构就是希望前端 后端都使用同一套逻辑 同一套代码

Nodejs出现后 这一设计方式的实现更加容易了 后端同样可以根据路径来加载js文件渲染指定的页面 而React又拥有renderToString 以及 renderToStaticMarkup方法

可以将react组建渲染成html字串

renderToString VS renderToStaticMarkup

这两者都是将 React元素变成原始的HTML, 且都是服务端在使用, 不同的是renderToStaticMarkup不会创建出额外的React的属性 比如 data-react-id等 主要是用于创建一个纯粹的静态页, 这样可以节省很多带宽

实现一个最简单的同构

就是希望服务器在响应某个请求所调用的逻辑

客户端对于该路径的处理也是使用同一套逻辑 (客户端对于路径处理 指的是运用了Hash或者Histroy State的SPA页面 对不同路径的处理)

更通俗一点的说法, 客户端和服务端对于同一个路径所作出的响应会使用到共同的文件(但并不表示对于同一个路径 他们处理的逻辑完全相同)

关于react-router的browserHistroy

如果你设置某个页面的router为 / 的话

访问这个页面的路径应该是 domian.xx:port/

之前没有理解browserHistroy 目标app是在一个很深的路径下

当时使用这个路径去访问

localhost/ReactStudy/RouterStudy/

自然就会出现 Location / Not match

Server端

我们知道Server端对于一个请求的处理, 就是根据不同的路径做出不同的响应 所以Server端的响应应该是一个完整的页面 之后在页面上发生的任何路径的改变, 都应该交给react route处理 Server不再参与后续的任务

这里Server使用koa来实现 服务端的路径处理使用koa-router

  let app = koa();
let router = koaRouter();
router.get(['/', '/home'], function*() { // 执行view插件
// 调用render方法 this是app的context
// 所以调用的this.render 也就是
this.body = this.render('Home', {
microdata: microdata,
mydata: {
nick: 'server render body'
}
},1);
});
app.use(router.routes()).use(router.allowedMethods());

可以看到整个响应体this.body的渲染由一个render方法完成

这个render调用了一个文件专门渲染服务端的页面 这个页面请求一个js文件 这个js文件就是整个客户端的逻辑

可能这个页面的一些渲染就是由和客户端通的组件得到的 但是并不一定会有共同的部分

这样服务器可以直接将一些信息渲染到页面中 解决了SEO的问题

但是这个过程非常的慢

慢的原因是因为这个render需要根据路径动态的require一些组件 然后解析等等

这些被require的组件如果是采用了ES6的方式编写 需要用 'babel-register' 来处理

它是一个Hook, 可以在require一个组件的时候做一些处理, 将ES6编译成ES5

由于这里是动态的处理这个编译的过程 这个服务端的响应就更加慢了


render() {
// 对象的解构赋值
const { microdata, title, children } = this.props;
return (
<html>
<head>
<meta charSet='utf-8' />
<meta httpEquiv='X-UA-Compatible' content='IE=edge' />
<meta httpEquiv='Cache-Control' content='no-siteapp' />
<meta name='renderer' content='webkit' />
<meta name='keywords' content='demo' />
<meta name='description' content='demo' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<title>{title}</title>
</head>
<body>
{children}
{this.renderScripts()}
</body>
</html>
);
}

需要注意的是, 并不是有了babel-loader 所有的ES6都可以顺利的变成ES5, Babel Online上可以看到关于ES6的语法有不同的presets的设置 默认情况下 class 的static 不能直接通过babel-loader编译 解决方案在这里http://jsrocks.org/2016/01/configuring-babel-6-for-node-js/

需要参数 你可以在.babelrc中加入下面的配置或者在webpack.config.js中添加params参数

{
"plugins": ["es2015", "stage-0"]
}

客户端

客户端最终的结果是一个OR多个js文件, 它包含了所有的页面上的逻辑以及页面之间的跳转(这里用的是react-router)

服务端生成了页面之后, 可以将一些参数(比如路径的参数) 直接写在页面中, 然后客户端从页面中获取这些参数值然后执行,

客户端主要逻辑

  render() {
let { isServer, mydata } = this.props;
return (
<Router history={browserHistory}>
<Route path="/" component={Nav}>
<Route path="/device/:deviceID" component={DeviceView}/>
</Route>
</Router>
);
}

等客户端的逻辑一开始执行 就会根据当前的url做匹配 执行特定的组件逻辑

React 同构的更多相关文章

  1. React同构直出原理浅析

    通常,当客户端请求一个包含React组件页面的时候,服务端首先响应输出这个页面,客户端和服务端有了第一次交互.然后,如果加载组件的过程需要向服务端发出Ajax请求等,客户端和服务端又进行了一次交互,这 ...

  2. 打造高可靠与高性能的React同构解决方案

    前言 随着React的兴起, 结合Node直出的性能优势和React的组件化,React同构已然成为趋势之一.享受技术福利的同时,直面技术挑战,在复杂场景下,挑战10倍以上极致的性能优化. 什么是同构 ...

  3. React同构直出优化总结

    收录待用,修改转载已取得腾讯云授权 作者:郭林烁 joeyguo 原文地址 React 的实践从去年在 PC QQ家校群开始,由于 PC 上的网络及环境都相当好,所以在使用时可谓一帆风顺,偶尔遇到点小 ...

  4. React 同构开发(二)

    React 同构 所谓同构,简单的说就是客户端的代码可以在服务端运行,好处就是能极大的提升首屏时间,避免白屏,另外同构也给SEO提供了很多便利. React 同构得益于 React 的虚拟 DOM.虚 ...

  5. React 同构开发(一)

    为什么要做同构 要回答这个问题,首先要问什么是同构.所谓同构,顾名思义就是同一套代码,既可以运行在客户端(浏览器),又可以运行在服务器端(node). 我们知道,在前端的开发过程中,我们一般都会有一个 ...

  6. 自制的React同构脚手架

    代码地址如下:http://www.demodashi.com/demo/12575.html Web前端世界日新月异变化太快,为了让自己跟上节奏不掉队,总结出了自己的一套React脚手架,方便日后新 ...

  7. 腾讯新闻构建高性能的 react 同构直出方案

    在腾讯新闻抢金达人活动 node 同构直出渲染方案的总结文章中我们整体了解了下同构直出渲染方案在我们项目中的使用.正如我在上篇文章结尾所说的: 应用型技术的难点不是在克服技术问题,而是在于能够不断的结 ...

  8. React同构起步

    React同构从0到1 前言 如果你想快速做react同构的新项目建议你去了解next.js等成熟框架,本教程仅限于想了解如何从0开始实现一个同构环境过程的同学,对于想改造现有spa项目的同学也很有帮 ...

  9. [转] React同构思想

    React比较吸引我的地方在于其客户端-服务端同构特性,服务端-客户端可复用组件,本文来简单介绍下这一架构思想. 出于篇幅原因,本文不会介绍React基础,所以,如果你还不清楚React的state/ ...

随机推荐

  1. JavaWeb限流QPS简易框架

    Java Web利用filter实现拦截请求,统计信息.并控制单台机器QPS. /** * 网络流量控制器 */ public class TrafficFilter implements Filte ...

  2. js 常用正则表达式(不断维护中)

    身份证:pattern="/^[1-9]{1}[0-9]{14}$|^[1-9]{1}[0-9]{16}([0-9]|[xX])$/"

  3. MySQL实用基础笔记

    /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限验证登录MySQL */ mysq ...

  4. SSH安全登录(远程管理)22端口

    Linux管理Linux 先加密再发送数据,更安全 一    联机加密工具         非对称钥匙对加密         安装    默认安装    openssh              启动 ...

  5. JavaScript 字符串常用操作纪要

    JavaScript 字符串用于存储和处理文本.因此在编写 JS 代码之时她总如影随形,在你处理用户的输入数据的时候,在读取或设置 DOM 对象的属性时,在操作 Cookie 时,在转换各种不同 Da ...

  6. python学习day7

    目录 一.反射 二.socket 三.socketserver 一.反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分 ...

  7. 无意发现vim里插入模式可以借助Alt键输入一些特殊字符

    无意发现vim里插入模式可以借助Alt键输入一些特殊字符.如: Alt+w: ÷ Alt+:: » Alt+f  :  æ Alt+ . :  ® Alt+ ? :  ¯...

  8. 用 for/in 在 Java 5.0 中增强循环

    这个方便的构造提供了什么?什么时候适用于代码? Brett McLaughlin (brett@newInstance.com), 作者/编辑, O'Reilly Media, Inc. 简介: fo ...

  9. thinkphp中的where()方法

    where方法的用法是ThinkPHP查询语言的精髓,也是ThinkPHP ORM的重要组成部分和亮点所在,可以完成包括普通查询.表达式查询.快捷查询.区间查询.组合查询在内的查询操作.where方法 ...

  10. tftp使用方法

    参数说明:-l   是local的缩写,后跟存在于Client的源文件名,或下载Client后               重命名的文件名.          -r   是remote的缩写,后跟Se ...