react服务端/客户端,同构代码心得
react服务端/客户端,同构代码心得
作者:webkixi
react服务端/客户端,同构代码心得
服务端,客户端同构一套代码,
大前端的梦想,为了省略重复的代码,却平添了不少烦恼,头发也白了,。。。。,妹子还在家等我.
目录结构问题
我们引用了很多的库,在开发前端代码的时候,习惯性的我们不会考虑到node端对于库的引用,这就是开始同构最大的痛点。整个目录结构需要调整。
减少调用层级
比如说开发前端时,有一个libs的库,在react的前端组件开发时,我们多次调用到libs里面的若干方法,这个时候,为了同构,需要将libs库做一个抽离,既是从前端代码中抽离到中间的部分。
这么说有点不好理解,简单配一个图吧。
FKP原来的结构
node -> fed -> libs -> component -> pages
大致上我们原来的结构都类似于这样,调整好之后的结构,如下:
node <-> libs <-> fed -> component -> pages
这样,我们将libs抽离到中间的部分,相对来说,在同构时,require的层级少了很多。但是还不够,为了 将react同构,我们还需要调整component的结构,如下:
node <-> libs <-> component <-> fed -> pages
如此这般,大致的结构算调整好了,接下来解决require的坑,让webpack和node端require做到无缝切换。 让require('libs/index'),这种引用兼容于两端。 在这里FKPJS用到了一个好用的包文件app-module-path,指定node端require的目录优先级,及自写了一个 include的方法(封装require),来简化require的调用深度。 并对libs库做更细化的抽象与提取,最后,FKPJS的libs结构做到如上所述。
组件结构问题
解决了目录结构问题后,为了做到同构,我们需要合理的组件结构,以方便两端的调用,经过本人的实践,FKPJS将组件分为三层,原子组件,组合组件,组件封装,如下图
原子 -> 组合 -> 封装
1. 原子组件(react/widgets)
适用node/fed,复用型组件,最小粒度化,产出纯结构,纯粹的react组件,封装了对数据的处理
2. 组合组件(react/modules/xxx/_component/xxx)
适用node/fed,组合不同的原子组件,并引入相关mixins,实现like redux,产出纯结构,纯react组件,传输数据
3. 组件封装(react/modules/xxx/yyy)
适用于前端,最表层,处理配置文件,可导入JQ等库实现内部逻辑、效果,并响应由业务层传导进来的方法,数据等等。
在FKPJS中封装的比较好的有两个组件,react/modules/pagination/pagi,react/modules/list/base_list.jsx,list组件有点复杂,我们先说下 pagi这个组件吧
pagi这个组件,用于分页,可前后端同构
Demo
前端业务中实现的代码
varPagi=require('modules/pagination/pagi'),// 初始化分页数据
pageData ={
total:60,
per:20,
url:'/',
query:'page='}Pagi(pageData,{
container:'pagi',begin:{ start:0, off:5},
itemMethod: bindItem
})
服务端同构的代码
// pages/pagi.jsvar _props ={
itemMethod:false,
listMethod:false,
itemClass:'',
listClass:'pagenation wid-12',
data:{
total:60,
per:20,
url:'/',
query:'page='},begin:{ start:0, off:5}}var reactHtml =yield react2html('react/modules/pagination/pagi', _props)
reactHtml[0]='<div class="pagi" id="pagi" >'+reactHtml[0]+'</div>'
oridata.pagi = reactHtml[0]return.....
组件封装
封装部分
// 封装方法function pagination(data, opts ){// 处理配置文件 var noop =false,
dft ={
container:'',
globalName:'_Pagi',
itemMethod: noop,
listMethod: noop,
itemClass:'',
listClass:'pagenation wid-12',
data:{
total:200,
per:10,
url:'/',
query:'page='},begin:{ start:0, off:7}}
dft = _.assign(dft, opts)if(!dft.container)returnfalse;if(data){
dft.data = data
}// fkp redux// 初始化组件数据// FKPJS使用SA代替redux// 需要在组合组件中引入,store的minxin
SA.set(dft.globalName,{
data: data,begin: dft.begin})// fkp redux // 将组建的action放到 SA 的全局名字中// 需要在 _Pagi组件中引入 store 这个mixinsvarPagi=_Pagi(dft.globalName)// 渲染组件
render(<Pagi data={data}begin={dft.begin} itemDefaultMethod={idm} itemMethod={dft.itemMethod} listMethod={dft.listMethod} itemClass={dft.itemClass} listClass={dft.listClass}/>,
document.getElementById(dft.container))}// 服务端同构,执行这个部分
pagination.server =function(){return_Pagi(true)};module.exports = pagination
组合组件
这里不贴出所有代码,部分
varList=require('../../../widgets/listView/list');varStore=require('../../../mixins/store');//引入这个就完成了reduxvar _storeName;var _jump =false;// List的item组件varPageItem=React.createClass({
componentDidMount:function(){var ele =React.findDOMNode(this),
mtd =this.props.itemMethod,
dmtd =this.props.itemDefaultMethod;if(dmtd &&typeof dmtd==='function'){
dmtd.call(ele, _storeName, mtd);}},.......
组合组件-算法部分
render:function(){if(this.state.data){var data =this.state.data,
newData =[],
pages = data.total/data.per,
pre,
aft,
half,begin=this.state.begin,........
组合组件-实现部分
function actRct( storeName ){// 根据storeName,可以实现多个组件,并redux化// for serverif(storeName===true){returnReact.createClass( pagenation );}// for client
_storeName = storeName||'_Pagi';var _rct = _.cloneDeep(pagenation);if( _rct.mixins && _rct.mixins.length ){
_rct.mixins.push(Store( _storeName ))//实现redux}else{
_rct.mixins =[Store( _storeName )]}returnReact.createClass( _rct );//返回react组件
原子组件
- List List source
- Item Item source
- Item 算法部分 Item算法实现
综上所述,做到两端同构的话,需要有一个全局的眼光,从基础的目录结构开始,到组件的结构,其实还有css的结构,html的结构,这里就不一一说明了,希望能抛砖引玉
文章目录
- 目录结构问题
- 组件结构问题
react服务端/客户端,同构代码心得的更多相关文章
- react服务端渲染同构报错Browser history needs a DOM
https://github.com/nozzle/react-static/issues/343 去掉了browserRouter就不报错了,但是又会有其他报错..
- TCP Socket服务端客户端(二)
本文服务端客户端封装代码转自https://blog.csdn.net/zhujunxxxxx/article/details/44258719,并作了简单的修改. 1)服务端 此类主要处理服务端相关 ...
- react服务端渲染(同构)
学习react也有一段时间了,使用react后首页渲染的速度与seo一直不理想.打算研究一下react神奇服务端渲染. react服务端渲染只能使用nodejs做服务端语言实现前后端同构,在后台对re ...
- react基础学习和react服务端渲染框架next.js踩坑
说明 React作为Facebook 内部开发 Instagram 的项目中,是一个用来构建用户界面的优秀 JS 库,于 2013 年 5 月开源.作为前端的三大框架之一,React的应用可以说是非常 ...
- 基于JAX-WS的Web Service服务端/客户端 ;JAX-WS + Spring 开发webservice
一.基于JAX-WS的Web Service服务端/客户端 下面描述的是在main函数中使用JAX-WS的Web Service的方法,不是在web工程里访问,在web工程里访问,参加第二节. JAX ...
- JAVA WEBSERVICE服务端&客户端的配置及调用(基于JDK)
前言:我之前是从事C#开发的,因公司项目目前转战JAVA&ANDROID开发,由于对JAVA的各种不了解,遇到的也是重重困难.目前在做WEBSERVICE提供数据支持,看了网上相关大片的资料也 ...
- eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二)
eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二) 接上篇博客,本篇博客主要包含两个内容: 4.使用Android studio创建webservice客 ...
- eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(一)
eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(一) 本篇博客主要包含五个内容: 1.CXF换将搭建以及eclipse配置CXF. 2.eclipse创建w ...
- TCP/IP网络编程之基于UDP的服务端/客户端
理解UDP 在之前学习TCP的过程中,我们还了解了TCP/IP协议栈.在四层TCP/IP模型中,传输层分为TCP和UDP这两种.数据交换过程可以分为通过TCP套接字完成的TCP方式和通过UDP套接字完 ...
随机推荐
- 关于.net中线程原子性的自我总结
首先来张图,一张 cpu的简图,仅从个人理解角度理解画的 大体 解释下这张图 这是 一张 i5的简图i5 大家都知道 是双核四线程,(超线程技术)l1,l2,l3是 1,2,3级缓存. Cpu工作:每 ...
- BZOJ 2208: [Jsoi2010]连通数 tarjan bitset
2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- c#匿名类 anonymous学习
感谢http://blog.csdn.net/jjx0224/article/details/5887589 感谢http://hi.baidu.com/guodong828/blog/item/cc ...
- Swift常用语法示例代码(一)
此篇文章整理自我以前学习Swift时的一些练习代码,其存在的意义多是可以通过看示例代码更快地回忆Swift的主要语法. 如果你想系统学习Swift或者是Swift的初学者请绕路,感谢Github上Th ...
- Android进阶2之APK方式换肤
public class MainActivity extends Activity { private Button defaultbutton = null; @Override public v ...
- 修复 MySQL 数据库结构错误 – mysql_upgrade升级
http://www.cnblogs.com/wjoyxt/p/5477072.html 不知道是不是每次更新 MySQL 软件之后都需要执行数据库升级指令?在我进行过的几次软件升级之后,总会在 My ...
- HOWTO install Oracle 11g on Ubuntu Linux 12.04 (Precise Pangolin) 64bits
安装了Ubuntu 12.04 64bit, 想在上面安装Oracle 11gr2,网上找了好多文档都没成功,最后完全参考了MordicusEtCubitus的文章. 成功安装的关键点:install ...
- HBase-配置说明
转载自:http://www.aboutyun.com/thread-7914-1-1.html hbase.rootdir这个目录是region server的共享目录,用来持久化Hbase.UR ...
- BootStrap2学习日记2--将固定布局换成响应式布局
概要:响应式页面是指页面根据浏览平台(尺寸)的不同显示不同的CSS. 原理:在Html的的头加入代码 <style> /*当浏览器宽度大于767是 采用括号里面的CSS样式*/ @medi ...
- C语言 字符串和数字转换函数
atof(将字符串转换成浮点型数) 相关函数 atoi,atol,strtod,strtol,strtoul 表头文件 #include <stdlib.h> 定义函数 double at ...