React-引领未来的用户界面开发框架-读书笔记(八)

第16章 架构模式

React主要功能在于渲染HTML。可以将其看成是MVC中的V,它不会影响到组件中直接调用AJAX请求之类的操作:

var TakeSurvey=React.CreateClass({getInitialData:function(){return{survey:null};},componentDidMount:funciton(){$.getJSON('/survey/'+this.props.id,function(json){this.setState({survey:json});});},render:function(){return <div>{this.state.survey.title}</div>}
});

路由

路由在单页面应用里为URL指定处理器函数。假设要为URL/surveys运行一个函数,函数的功能是从服务器加载用户,然后渲染<LIstSurveys>组件。

路由有很多种,在服务器端也存在路由,有一些路由可以在客户端和服务器端运行。

React仅仅是一个一个的渲染类库,没有路由的功能,不过有很多路由模块可以搭配React使用。

Backbone.Router:

Backbone是单页面应用类库,采用了MVX(Model-View-Whatever)架构。其中X指代控制器(Controller),通常指代的是路由。对Backbone来说就是如此。

Backbone是模块化的,你可以只用它的路由功能。它可以和React很好的搭配在一起使用。例如:

var SurveysRouter =Backbone.Router.extend({routes:{"surveys":"list"},list:function(){React.renderComponent(<ListSurveys />,document.querySelector('body'));}
});

路由需要处理URL中动态的部分和queryString。Backbone.Router具备这样的功能,示例如下:

// surveys_routers.js
varSurveysRouter=Backbone.Router.extend({routes:{"surveys":"list","surveys/:filter":"list"},list:function(filter){React.renderComponent(<ListSurveys filter={filter}/>,document.querySelector('body));},
});

在上面的例子中,给定一个比如/surveys/active这样的URL地址,那SurveysRouter#list的参数filter就是active。

Aviator

与Backbone.Router不同,Aviator是一个独立的路由类库。

在Aviator中,路由定义与RoutetTarget是相互独立的。即Aviator不关心RouteTarget的实现和行为,仅试着调用赋值在它上面的方法。

比如这样一个RouteTarget:

// surveys_route_target.js
varSurveysRouteTarget={list:function(){React.renderComponent(<ListSurveys>,docment.querySelector('body'););}
};

与这个对象对应,需要有一份路由的配置(整个应用只能有一个唯一的路由配置),这个配置通常写在另一个独立的文件中。

// routes.js
Aviator.setRoutes({'/surveys':{target:UsersRouteTarget,'/':'list'}
});
//让Aviator把url分派到RouteTarget
Aviator.dispatch();

设置RouteTarget处理函数:

// route.js
Aviator.setRoutes({'/surveys':{target:usersRouteTarget,'/':'list','/:filter':'list'}
});// surveys_route_target.js
varSurveysRouteTarget={list:function(request){React.renderComponent(<ListSurveys filter={request.param.filter}/>,doucument.querySelector('body'));}
}

Aviator有一个很棒的特性就是可以使用多个RouteTarget,例如下main这样的路由配置:

// route.js
Aviator.setRoutes({target:AppRouteTarget,'/*':beforeAll,'/surveys':{target:UsersRouteTarget,'/':'list''/:filter':'list'}
});

对于'/surveys/active'这样的URL,Aviator会先调用appRouteTarget.beforeAll在调用UsersRouteTarget.list——只要匹配,Action的数量并不受限制。你还可以定义路由离开时的执行函数,当用户从匹配的路由离开时,定义过的执行函数会从内到外依次执行。

react-router

react-router不同于其他的路由,它完全是有ReactComponent构成的。

路由被定义成了组件,路由的处理器也是组件。

按照react-router的写法路由是这样的:

var appRouter=(<Routes location="history"><Route title="SurveyBuilder" handler={App}><Route name="list" path="/"handler={ListSurveys}/}<Route title ="Add Survey to SurveyBuilder"name="add" path="/add_survey" handler={AddSurvey}/><Route name ="edit" path="/surveys/:surveyId/edit" handler={EditSurvey}/><Route name="take" path="/surveys/:surveyId"handler={TakeSurveyCtrl} /><NotFound title="page Not Found"handler={NotFoundHandler}/></Route></Routes>
);

每一个处理器就是一个对应着特定页面的组件。把上面的路由作为顶层的组件渲染来启动它。

React.renderComponent(appRouter,document.querySelector('body')
);

就像其他的路由一样,react-router也有类似的参数概念。 比如路由'/surveys/:surveyId'会把surveyId属性传给TakeSurveyCtrl组件。

Link是react-router提供的很酷的特性之一。你可以使用它来导航,它可以自己对应到路由上。而且它还能自动给链接添加active样式,标记当前活动页面。

使用react-router Link组件后组件看起来是这样的:

varMainNav=React.createClass({render:function(){retrun(<nav className='main-nav' role='navigation'><ul className='nav navbar-nav'><li><Link to='list'>All Surveys </link></li><li><Link to="add" >AddSurvey</Link></li></ul></nav>);}
});

Om(ClojureScript)

Om是比较流行的React的ClojureScript接口。通过ClojureScript的不可变数据结构,Om可以飞快地重新渲染整个应用,而且每个操作都可以很容易地被存为快照,用来实现撤销等功能。

Om组件看起来是这样:

(ns example
(:require [om.core :as om :include-macros true][om.dom:as dom :include-macros true]))
(defn App[data owner](reifyom/IRender(render[this](dom/h1 nil (:text data)))))
(om/rootApp {text "Survey Builder"}{:targer(. js/document (querySelector "body"))})

它将被渲染为<h1>SurveyBuilder</h1>

Flux

前面的架构模式都是随着React的开源而出现的。但Flux是React的原作者从一开始就设计好的。

Flux是Facebook引入的架构模式。它为React提供了一套单向数据流模式,这个模式很容易审查数据修改的过程和原因。实现Flux起来只需要很少的脚手架和代码。

Flux由三个主要的部分组成:Store,Dispatcher和视图(即React Component)。Action作为创建Dispatcher的语义化接口的辅助方法,可以当做Flux模式的第四部分。

顶层的React组件类似于一个控制视图(Controller-View)。控制视图的组件与Store进行交流并协助其与子组件进行通信。这与iOS开发中的控制视图差别不大。

Flux模式里的每个部分都是独立的,强制进行了严格的隔离,通过隔离来保证每个部分都易于测试。

Flux的数据流

Flux使用的是单向数据流。这在已有的MVC框架中显得很特别,但也带来了一些独特的好处。因为Flux没有用双向绑定,所以他的应用很容易审查问题。状态是在Store(Store是Flux中数据的拥有者)中维护的,因此很容易跟踪。Store通过change方法传送数据,触发视图的渲染。用户的输入行为会出发Action通过Dispatcher进行分派,以此传送数据到专门处理特性Action的Store中。

Flux各个部分

Flux由实现特定功能的几个部分组成。在单向数据流中,Flux的每个部分获取上游输入的内容进行处理,然后向下游发送它的输出内容。

  • Dispatcher——应用的中心仓库
  • Action——应用的DSL(Domain Specific Language)
  • Store——业务逻辑和数据交互
  • 视图——渲染应用组件树

Dispatcher

我们从Dispatcher开始,因为他是所有用户交互和数据流的中心仓库。在Flux模式当中Dispatcher是一个单例。

Dispatcher负责在Store上注册回调以及管理它们之间的依赖关系。用户的Action会流入Dispatcher。数据会传送到注册过Action的Store当中。

我们的Survey Builder中包含了一个相对简单但有效地管理单个Store的Dispatcher。然而,随着应用的扩张,你一定会遇到需要管理多个Store和他们之间依赖的情况。这种情况我们会在后面讨论。

Action

从用户的角度看,这是Flux的起点。每个在UI上的行为都会创建一个被发送到Dispatcher的Action。

尽管Action不是Flux模式真正的部分,但他们构成了应用的DSL。用户操作被转化成为有含义的Dispatcher Action——Store可以依次调用相应的行为。

Store

Store负责封装应用的业务逻辑与应用数据交互。Store通过注册Action来选择相应哪些Action。Store把内部的数据通过更改时的change事件发送到React的组件当中。

保持Store严格的独立非常重要。

  • Store中包含应用的所有数据
  • 应用其他任何部分都不知道怎么操作数据——Store是应用中唯一的数据发生改变的地方
  • Store没有赋值——所有的更改都是由Dispatcher发送到Store的。新的数据随着Store的更改事件传送回到应用中。

控制视图

应用的组件层级一般会有一个顶层的组件负责与Store交互。简单的应用只有一个控制视图,复杂一些的应用可能会有多个。

管理多个Store

当一个Store依赖另一个的时候,数据的关系会变得复杂,比如一个Store要在另一个Store响应同一个Action之前先完成自身的调用。

第17章 其他使用场景

React不仅是一个强大的交互式UI渲染类库,而且提供了一个用于处理数据和用户输入的绝佳方法。它倡导可重用并且易于测试的轻量级组件。不仅在Web应用中,这些重要的特性同样适用于其他的技术场景。例如:

  • 桌面应用
  • 游戏
  • 电子邮件

  • 绘图

本系列文章转自http://me.molinblog.com/,感谢作者。
http://me.molinblog.com/blog/developing-a-react-edge-8.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/286733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三)mybatis 二级缓存,整合ehcache

mybatis-config.xml <setting name"cacheEnabled" value"true" /> PersonMapper.xml <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http:…

confluence5.8.10的使用

之前在windows上安装了confluence5.8.10,结果有一天知什么缘故&#xff0c;数据库数据损坏&#xff0c;知识库彻底打不开了&#xff0c;所有的文档都付之东流&#xff0c;真的不是一般心痛。因此考虑将其装到linux机器上&#xff0c;因为tomcat和mysql实际上都为了linux而生的&…

Android之提示Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider

1 问题 接入SDK提示错误如下 java.lang.RuntimeException: Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider: java.lang.IllegalStateException: 2 解决办法 在AndroidManifest.xml文件下面配置如下 在application目录下面配置如下&#xff0c;…

RPA之PAD(Power Automate Desktop)组件开发

本文由网友蓝创精英团队投稿&#xff0c;欢迎转载、分享原文作者&#xff1a;蓝创精英团队原文链接&#xff1a;https://blog.csdn.net/i2blue/article/details/125040323其实&#xff0c;PAD&#xff0c;现在官方文档还没有对外组件式或者插件式开发接口。但是&#xff0c;有一…

【地图学】高斯-克吕格(Gauss-Kruger)投影原理、应用详解(3°带、6°带)

一、高斯克吕格投影概述 德国数学家、物理学家、天文学家高斯于19 世纪20 年代拟定,后经德国大地测量学家克吕格于1912 年对投影公式加以补充,故称为高斯-克吕格投影(Gauss-Kruger,简称GK),又名"等角横切椭圆柱投影”。中央经线和赤道投影为相互垂直的直线,其它经线…

Linux安装 微信开发者工具(deepin linux ubt)

一.环境:: deepin linux15.4.1 二.安装过程: 2.1 安装wine sudo apt-get install wine 2.2 安装nwjs-sdk 2.2.1 下载linux版nwjs-sdk wget https://dl.nwjs.io/v0.25.4/nwjs-sdk-v0.25.4-linux-x64.tar.gz 2.2.2 解压nwjs-sdk tar xvf nwjs-sdk-v0.25.4-linux-x64.tar.gz 2.2…

Python 3.6学习笔记(一)

开始之前 基础示例 Python语法基础&#xff0c;python语法比较简单&#xff0c;采用缩紧方式。 # print absolute value of a integer a 100 if a > 0:print(a) else:print(-a) 可以看到&#xff0c;注释以#开头&#xff0c;python的变量不需要任何前缀&#xff0c;行结束不…

小程序的 HelloWord 01《 程序员变现指南之 微信QQ 小程序 真的零基础开发宝典》

本系列教程是针对粉丝的变现教程&#xff0c;还不是粉丝的可以关注我并且到社区&#xff1a;https://bbs.csdn.net/topics/603436232 进行打卡&#xff0c;不是老粉的也可以获取最终的技术变现学习&#xff0c;最终还有详细的变现教程等你来。 前言 《 程序员变现指南之 微信…

octave中的一些基本操作

1.矩阵的表示&#xff1a;v [1 2 2] %表示1行3列的矩阵 v [1; 2; 2] %表示3行1列的矩阵 v [1 2; 2 3; 4 5] %3*2矩阵 size(v) % 求v的行与列 length(v) %求v的列 2.几个基本矩阵的表示&#xff1a;1&#xff09;s ones(2, 4) %2*4全1矩阵 2&#xff09;m zeros(3, 4) %3…

Docker 日志最佳实践

当运行在 docker 容器中的应用程序打印日志时&#xff0c;日志会输出到标准输出流 stdout 和标准错误流 stderr。容器日志驱动可以访问这些流&#xff0c;并将日志发送到文件、本机运行的日志收集器或远端的日志服务端点&#xff08;endpoint&#xff09;。本文将介绍选择不同的…

Android之提示A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution

1 问题 编译项目的时候提示错误如下 A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution 2 原因 有2次我写room数据库的时候都提示这个 ColumnInfo(name "isAddBookmark")var isAddBookmark falseColumnInfo(name "…

一个获取a标签传值的函数

//获取url查询参数 var getUrlParams function () {var href"",params;return function (key,url) {if(url) {href url;params null;} else if(!url && !href) href window.location;//console.log(href);if(!params) {params {};var search href.sea…

【大地信】新时代GIS发展趋势与未来展望

一、你必须知道的国内外知名学者 1. RogerTomlinson(罗杰汤姆林森)---GIS之父 Roger Tomlinson从1963年开始创建世界上第一个地理信息系统,即加拿大地理信息系统(CGIS)。因此,Tomlinson被誉为地理信息系统之父。 RogerTomlinson(1933.12---2014.2.9) 2. Michael Fran…

Python3.6学习笔记(二)

Python 的高级特性 切片 对于指定索引范围取值的操作&#xff0c;Python提供了slice方法&#xff0c;类似于Excel中数据透视表的切片器。 >>> L [Michael, Sarah, Tracy, Bob, Jack’] #声明一个List&#xff0c;取前三个值 >>> L[0:3] #表示从0开始&…

小程序获取头像试试水 02《 程序员变现指南之 微信QQ 小程序 真的零基础开发宝典》

本系列教程是针对粉丝的变现教程&#xff0c;还不是粉丝的可以关注我并且到社区&#xff1a;https://bbs.csdn.net/topics/603436232 进行打卡&#xff0c;不是老粉的也可以获取最终的技术变现学习&#xff0c;最终还有详细的变现教程等你来。 前言 《 程序员变现指南之 微信…

VNX NETAPP NAS 备份恢复

做多少次快照的时间是自定义 的&#xff0c;例如可以每隔4小时做一次。 例如有A&#xff0c;B&#xff0c;C&#xff0c;D四个文件。 1&#xff09;第一次快照&#xff08;COW&#xff09;&#xff1a; 快照是瞬时的&#xff0c;拍照时候创建了一个快照空间&#xff0c;例如20%…

Git之cherry-pick命令

1 需求 有时需要把某远程分支(比如dev分支)的某一次提交合并到另一远程分支(比如master分支),这就需要用到git cherry-pick命令。 比如我们现在有0.1分支和0.2分支,我在0.1分支上提交了最后一次代码,推上去了,现在需要合并这次提交到0.2 2 操作步骤 我们先到0.1分支…

【空间数据库】时空数据库,时态数据模型详解

一、时态空间数据库概述 现实世界的数据不仅与空间相关,而且与时间相关。在许多应用领域,如环境监测、抢险救灾、交通管理、医疗救援等,相关数据随着时间变化而变化,称之为时态数据。很多空间数据库应用都涉及时态数据,这些应用不仅需要存取空间数据库的当前状态,也需要存…

输出日志实例改成用Spring的AOP来实现

1.采用Interception Around通知的形式实现 Interception Around通知会在Join Point的前后执行&#xff0c;实现Interception Around通知的类需要实现接口MethodInterceptor。其实现思路是&#xff1a; 1&#xff09;首先实现接口MethodInterceptor&#xff0c;在Invoke()方法里…

基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入

系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客&#xff1f;基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.N…