React 自学

chapter one React新的前端思维方式

React的首要思想是通过组件(Component)来开发应用。所谓组件,简单说,指的是能够完成某个特定功能的独立的、可重用的代码。

基于组件的应用开发是广泛使用的软件开发模式,用分而治之的方法,把一个大的应用分解成若干的小组件,每个组件只关注某个小范围的特定功能,但是把组件组合起来,就能构成一个功能庞大的应用。如果分解功能的过程足够巧妙,那么每个组件可以在不同场景下重用,那样不光可以构建庞大的应用,还可以构建出灵活的应用。打个比方,每个组件是一块砖,而一个应用是一座楼,想要一次锻造就构建一座楼是不现实的。实际上,总是先锻造很多砖,通过排列组合这些砖,才能构建伟大的建筑。

React非常适合构建用户交互组件。

jsx 是进步还是退步?

多年来,业界一直流行三次分离,即html(结构)、css(表现)、js(逻辑)分离,一般会写在不同的文件之中。

而jsx把类似HTML的标记语言和javascript混在一起了,但是,随着时间的推移,业界分离的认识有了改变,将html,css,js这三种语言分在三种不同的文件里面,实际上是把不同技术分开管理了,而不是逻辑上的“分而治之”。

html之中的onclick与jsx之中的onClick的区别:

  • onclick添加的时间处理函数是在全局环境下执行的,这污染了全局环境,很容易产生意料不到的后果;
  • 给很多DOM袁术添加onclick时间,可能会影响网页的性能,毕竟,网页需要的时间处理函数越多,性能就会越低;
  • 对于使用onclick的DOM元素,如果要动态地从DOM树中删除的话,需要把对应的时间处理器注销,加入忘了注销,就可能造成内存泄露,这样的bug,很难被发现。

在jsx之中,onClick挂载的每个函数,都可以控制在组件范围内,不会污染全局空间。

我们在jsx中看到了一个组件使用了onClick,但并没有产生直接使用onclick的html,而是使用了事件委托(event delegation)的方式处理点击事件,无论有多少个onClick出现,其实最后都只在DOM树上添加了一个事件处理函数,挂载在最顶层的DOM节点上。所有的点击事件都被这个事件处理函数捕获,然后根据具体组件分配给特定函数,使用事件委托的性能当然比每个onClick都挂载一个事件处理函数要高。

因为React控制了组件的生命周期,我们还可以在React组件中定义样式。

分解Reac应用

React的理念,归结为一个公式,就像下面这样:

UI = render(data)

用户看到的界面(UI),应该是一个函数render执行结果,只接受数据(data)作为参数。这个函数是一个纯函数,所谓纯函数,指的的是没有任何副作用,输出完全依赖于输入的函数,两次函数调用如果输入相同,得到的结果也绝对相同。如此一来,最终的用户界面,在render函数确定的情况下完全取决于输入数据。

对于开发者来说,重要的是区分开那些是属于data,哪些属于render,想要更新用户界面,要做的就是更新data,用户界面自然会做出相应,所以react实际的也是“响应式编程”(reactive programming)的思想,这也就是react为什么叫做react的原因。

Virtual Dom

既然react应用就是通过重复渲染来实现用户交互,你可能会有一个疑惑:这样的重复渲染会不会效率太低了呢?在jQuery的实现方式中,我们可以清楚地看到每次只有需要变化的哪一个DOM元素被修改了;可是,在react的实现方式中,看起来每次render函数被调用,都需要把整个组件重新绘制一次,这样看起来有点浪费。

事实并不是这样,react利用virtual dom,让每次渲染都只重新渲染最少的DOM元素。要了解virtual dom,就要先了解dom,dom是结构话文本的抽象表达式,特定于web环境中,这个结构化文本就是html文本,html中的每个元素都对应dom中某个节点,这样,因为html元素的逐级包含关系,dom节点自然就构成了一个树形结构,成为DOM树。

浏览器为了渲染html格式的网页,会先将html文本解析以构建dom树,然后根据dom树渲染出用户看到的界面,当要改变界面内容的时候,就去改变dom树上的节点。

web前端开发关于性能优化有一个原则:尽量减少DOM操作。虽然dom操作也只式一些简单的javascript语句,但是dom操作会引起浏览器对网页进行重新布局,重新绘制,这就是一个比javascript语句执行慢很多的过程。

如果使用mustache或者hogan这样的模板工具,那就是生成html字符串赛到网页中,浏览器又要做一次解析生产新的DOM节点,然后替换DOM树上对应的子树部分,这个过程的肯定效率不高。虽然jsx看起来很像是一个模板,但是最终会被babel解析为一条条创建react组件或者html元素的语句,神奇之处在于,react并不是通过这些语句直接构建DOM树,而是首先构建virtual dom。

既然dom树是对html的抽象,那virtual dom就是对dom树的抽象。virtual dom不会触及浏览器部分,只是存在于javascript空间的树形结构,每次自上而下渲染react组件时,会对比这一次产生的virtual dom和上一次渲染的virtual dom,对比就会发现差别,然后修改真正的dom树时就只需要初级差别中的部分就行。

jquery的方式直观易懂,对于初学者十分适用,但是当项目逐渐变得庞大时,用jquery写出的代码往往互相纠缠,不同的事件直接修改dom元素。

使用react的方式,就可以避免构建这样复杂的程序结构,无论何种事件,引发的都是react组件的重新渲染,至于如何只修改必要的dom部分,则完全交给react去操作,开发者并不需要关系。react利用函数式编程的思维来解决用户界面渲染的问题,最大的优势式开发者的效率会大大提高,开发出来的代码可维护性和可阅读性也大大增强。

chapter two 设计高质量的react组件

作为一个合格的开发者,不要只满足于编写出了可以运行的代码,而要了解代码背后的工作原理;不要只满足于自己编写的程序能够运行,还要让自己的代码可读而且易于维护。这样才能开发出高质量的软件。

作为软件设计的通则,组件的划分要满足高内聚(high cohesion)低耦合(low coupling)的原则。

高内聚指的式把逻辑紧密的相关内容放在一个组件中。用户界面无外乎内容、交互行为和样式。传统上,内容由html表示,交互行为放在javascript代码文件中,样式放css文件中定义。这虽然满足一个功能模块的需要,却要放在三个不同的文件中,这其实不满足高内聚的原则。react却不是这样,展示内容的jsx、定义行为的javascript代码,甚至定义样式的css,都可以放在一个javascript文件中,因为他们本来就是为了实现一个具体的目的而存在的,所以说react天生具有高内聚的特点。

低耦合指的式不同组件之间的依赖关系要尽量弱化,也就是每个组件要尽量独立。保持整个系统的低耦合度,需要对系统中的功能有充分的认识,然后根据功能点划分模块,让不同的组件去实现不同的功能,这个功夫还在开发者身上,不过,react组件的对外接口非常规范,方便开发者设计低耦合的系统。

react组件的数据

"差劲的程序要操心代码,优秀的程序要操心数据结构和他们之间的关系。"

react组件的数据分为两种,prop和state,无论prop或者state的改变,都可能引发组件的重新渲染,那么,设计一个组件的时候吗,什么时候选择prop什么时候选择用state呢?原则很简单,prop是组件对外的接口,state是组件内部的状态,对外用prop,内部用state。

每个react组件都是独立存在的模块,组件之外的一切都是外部世界,外部世界就是通过prop来和组件对话的。

当prop的类型不是字符串类型时,在jsx中必须使用花括号{}把prop值包住,所以style的值有两层花括号,外层花括号代表是jsx的语法,内层的花括号代表这是一个对象常量。

react中的prop

prop 传值分析:

class Counter extends Component {
constructor(props){
super(props); this.onClickIncrementButton = this.onClickIncrementButton.bind(this);
this.onClickDecrementButton = this.onClickDecrementButton.bind(this); this.state = {
count:props.initValue || 0;
}
}
}

如果一个组件需要定义自己的构造函数,一定要记得在构造函数的第一行通过super调用父类也就是React.Component的构造函数。如果在构造函数中没有调用super(props),那么组件实例被构造之后,类实例的所有成员函数就无法通过this.props访问到父组件传递过来的props值。很明显,给this.props赋值是React.Component构造函数的工作之一。

在Counter的构造函数中还给哦i昂贵成员绑定了当前this的执行环境,因为es6方法构造的react组件类并不自动给我们绑定this到当前实例对象。在构造函数的最后,我们可以看到读取传入prop的方法,在构造函数中可以通过参数props获得传入prop值,在其他函数中则可以通过this,props访问传入的prop的值,比如在counter组件的render函数中,我们就是通过this.props获得传入的caption ,render函数代码如下:

render(){
const { caption } = this.props;
return <div>
<button style={buttonStyle} onClick={this.onClickIncrementButton}>+</button>
<button style={buttonStyle} onClick={this.onClickDecremnetButton}>-</button>
<span>{caption} count:{ this.state.count } </span>
</div>
}

react的state

驱动组件渲染过程的除了prop,还有state,state代表组件的内部状态。由于react组件不能修改传入的prop,所以需要i记录自身数据变化,就要使用state。

通常在组件类的构造函数结尾出初始化state,在counter构造函数中,通过this.state的赋值完成了对组件state的初始化。代码如下:

constructor(props){
// ...
this.state = {
count:props.initValue || 0;
}
}

于2017.10.2

differences between react element and react component

react elements are plain objects.They describe what you want to see on the screen.React elements are inmutable .Once you create an element,you can't change its children or attributes.An element is like a single frame in a movie :it represents the UI at a certain point in time.

react components are like Javacript functions.they accept arbitrary inputs (called "props") and return react elements describing what should appear on the screen.

functional and class components

React componets must act like pure functions with repect to their props.

Locak state is exactly that:a feature available only to a Class.

什么是组件

能够完成某个特定功能的独立可重用的代码。基于组件是广泛使用的软件开发模式,是分而治之的方法。把大的应用分解成为若干个小的组件,每个组件专注某个特定的功能。把组件合起来就能够成为一个功能庞大的应用。如果组件功能分解足够巧妙,每个组件可以在不同的场景下重用,可以构建出庞大灵活的应用。

prop

当外部世界传递一些数据给React组件,一个最直接的方式就是通过prop;同样React组件要反馈数据给外部数据,也可以用prop,因为Prop的类型限于纯数据,也可以是函数,函数类型的prop等于让父组件交给子组件一个毁掉函数,子组件在恰当的实际调用函数的类型prop,可以带上必要的参数,这样就可以反过来把信息传递给外部的世界。

哈哈:看到这里,不禁想到了一个例子,一个也是在别处调用的情况,就是常见的跨域方式,如jsonp,script标签请求的数据就返回就是回掉一个之前已经定义好的函数。对于后端的数据处理来说,是相当于一个黑匣子。对于父子组件而言,也相当一个黑匣子里面调用数据。两个例子都是一个回掉函数的作怪。常言到,函数是代码的分割,此话可当真

react redux学习之路的更多相关文章

  1. React Redux学习笔记

    React Router React Router 使用教程 Redux中间件middleware [译]深入浅出Redux中间件 Redux学习之一:何为middleware? ES6 ES6新特性 ...

  2. React+Redux学习笔记:React+Redux简易开发步骤

    前言 React+Redux 分为两部分: UI组件:即React组件,也叫用户自定义UI组件,用于渲染DOM 容器组件:即Redux逻辑,处理数据和业务逻辑,支持所有Redux API,参考之前的文 ...

  3. 走进React的学习之路

    GIT: 代码管理.https://git-scm.com/book/zh/v2 ES6: http://www.infoq.com/cn/minibooks/ES6-in-Depth Webpack ...

  4. react.js学习之路二

    看react.js对我来说真的不是难不难的问题,问题是我的思路太难转变了,真是坑死我了,react里面的坑也很多.算了,这些抱怨没啥用,记录一下今天学习的内容. 今天看了to-do-list经典示例 ...

  5. react.js学习之路六

    学习react中,我一直认为,总组件里面才有构造函数,但是我才发现我的观点是错误的,构造函数是可以出现在子组件里面的. 今天有一个错误是点击增加/减少input框里面 的数值 我一直在寻找input框 ...

  6. react.js学习之路五

    最近没时间写博客,但是我一直在学习react,我发现react是一个巨大的坑,而且永远填不完的坑 关于字符串的拼接: 在react中,字符串的拼接不允许出现双引号“” ,只能使用单引号' ',例如这样 ...

  7. react.js学习之路四

    针对学习react.js中,我感觉最大的疑惑点就是bind(this)的绑定和指向问题了,我被这个问题弄的头昏,有时候调用组件的时候,直接显示undefined,不存在这个组件,当时的心情是崩溃的,整 ...

  8. react.js学习之路三

    学习react.js,知识点整理: 1.props和state: props是相对于父级来说,固定的不会改变的内容.一般会先定义一个变量,则在父级中进行引用, var user = "liu ...

  9. react.js学习之路一

    今天新老大来了,我们要学习他使用的框架react.js,现在是两眼一抹黑,对于我这个前端菜鸟来说,是真正的重新开始,好了,不说那么多了,开始随便记录我的学习,之后再整理内容. (1)对于react来说 ...

随机推荐

  1. 了解Job和JobDeatil ,JobDataMap (三)

    一:定义 Job:实现任务逻辑的接口. JobDeatil:JobDeatil为Job提供了许多设置属性,以及JobDataMap成员变量属性,他用来储存特定的Job实例状态信息,调度器需要使用Job ...

  2. linux nohup

    nohup RAILS_ENV=production bundle exec XXXX & nohup RAILS_ENV=production bundle exec XXXX >/d ...

  3. #8 Python数学方法

    前言 前几节了解了Python的不同数据类型,有小伙伴会问,不同的数据类型之间是否可以相互转换?肯定是可以的,本篇博文主要记录数字类型的转换,其他类型的相互转换会在下几节记录,Here we go! ...

  4. 判断使用设备是PC还是phone

    <script type="text/javascript"> //如果是手机设备,则.. if(/Android|webOS|iPhone|iPod|BlackBer ...

  5. Mybatis之基于XML的调用存储过程与手动回滚事务

    一.调用存储过程 一.返回单个值 1.存储过程准备 这里先创建一个存储过程,传入参数为age,传出参数为count.然后先测试一下是否正确. CREATE DEFINER=`root`@`localh ...

  6. Infopath 2013 通过UserProfileService读取AD用户信息

    我刚刚看过什么C#文章获得当前用户使用Web服务的详细信息. 其实无需编写任何代码,可以实现完全相同的结果.所以我在这里简单的介绍一下: *如果你已经熟悉这个,这个篇文章可以跳过. *此介绍是建立在I ...

  7. (转)分享一个技巧,利用批处理调用ruby脚本(可能你为路径苦恼)

    #关闭命令显示 @echo off #提示信息 echo Now,listing the controller,please not shutdown the DOS File! #切换到当前路径,. ...

  8. Asp.net中GridView详解《转》

    ASP.NET服务器控件GridView 1         ASP.NET 服务器控件GridView使用 本教程不介绍服务器端控件的呈现,事件处理,状态等理论知识,只介绍服务器端控件的使用操作,如 ...

  9. java连接OPC之——Windows7 With SP1 网络OPC的DCOM配置

    由于 OPC(OLE for Process Control)建立在 Microsoft 的 COM(COmponent Model)基础 上,并且 OPC 的远程通讯依赖 Microsoft 的 D ...

  10. maven+eclipse创建web项目

    第一步,创建maven工程,如下图步骤 选择maven-archetype-webapp,然后next 输入GroupId和ArtifactId,Package可以为空,然后finish 新创建的ma ...