深入浅出React和Redux

作者程墨分类计算机-编程设计
推荐值72.5 %来源微信读书
笔记数量28评论数量

第1章 React新的前端思维方式

1.2 增加一个新的React组件

  • 使用React.createClass是一种过时的方法。在本书中,我们只使用ES6的语法来构建组件类

1.2.1 JSX

  • React判断一个元素是HTML元素还是React组件的原则就是看第一个字母是否大写,如果在JSX中我们不用ClickCounter而是用clickCounter,那就得不到我们想要的结果

1.2.2 JSX是进步还是倒退

  • onclick添加的事件处理函数是在全局环境下执行的,这污染了全局环境,很容易产生意料不到的后果;
  • 所有的点击事件都被这个事件处理函数捕获,然后根据具体组件分配给特定函数,使用事件委托的性能当然要比为每个onClick都挂载一个事件处理函数要高。

1.4 React的工作方式

1.4.2 React的理念

  • 对于开发者来说,重要的是区分开哪些属于data,哪些属于render,想要更新用户界面,要做的就是更新data,用户界面自然会做出响应,所以React实践的也是“响应式编程”(Reactive Programming)的思想

1.4.3 Virtual DOM

  • Virutal DOM不会触及浏览器的部分,只是存在于JavaScript空间的树形结构,每次自上而下渲染React组件时,会对比这一次产生的Virtual DOM和上一次渲染的Virtual DOM,对比就会发现差别,然后修改真正的DOM树时就只需要触及差别中的部分就行。

第2章 设计高质量的React组件

2.2 React组件的数据

2.2.1 React的prop

  • 当prop的类型不是字符串类型时,在JSX中必须用花括号{}把prop值包住,所以style的值有两层花括号,外层花括号代表是JSX的语法,内层的花括号代表这是一个对象常量。
  • 因为React要求render函数只能返回一个元素
  • 一定要记得在构造函数的第一行通过super调用父类也就是React.Component的构造函数。如果在构造函数中没有调用super(props),那么组件实例被构造之后,类实例的所有成员函数就无法通过this.props访问到父组件传递过来的props值。很明显,给this.props赋值是React.Component构造函数的工作之一。
  • 其他函数中则可以通过this.props访问传入prop的值
  • propTypes虽然能够在开发阶段发现代码中的问题,但是放在产品环境中就不大合适了。

2.2.2 React的state

  • 组件的state必须是一个JavaScript对象,不能是string或者number这样的简单数据类型
  • 直接修改this.state的值,虽然事实上改变了组件的内部状态,但只是野蛮地修改了state,却没有驱动组件进行重新渲染,既然组件没有重新渲染,当然不会反应this.state值的变化;而this.setState()函数所做的事情,首先是改变this.state的值,然后驱动组件经历更新过程,这样才有机会让this.state里新的值出现在界面上

2.3 组件的生命周期

  • 装载过程(Mount),也就是把组件第一次在DOM树中渲染的过程;□ 更新过程(Update),当组件被重新渲染的过程;□ 卸载过程(Unmount),组件从DOM中删除的过程

2.3.1 装载过程

  • 在ES6语法下,类的每个成员函数在执行时的this并不是和类实例自动绑定的。而在构造函数中,this就是当前组件实例,所以,为了方便将来的调用,往往在构造函数中将这个实例的特定函数绑定this为当前实例
  • 在render函数中去调用this.setState毫无疑问是错误的,因为一个纯函数不应该引起状态的改
  • 虽然componentWillMount都是紧贴着自己组件的render函数之前被调用,componentDidMount可不是紧跟着render函数被调用
  • 之所以会有上面的现象,是因为render函数本身并不往DOM树上渲染或者装载内容,它只是返回一个JSX表示的对象,然后由React库来根据返回对象决定如何渲染。而React库肯定是要把所有组件返回的结果综合起来,才能知道该如何产生对应的DOM修改。所以,只有React库调用三个Counter组件的render函数之后,才有可能完成装载,这时候才会依次调用各个组件的componentDidMount函数作为装载过程的收尾。
  • componentDidMount只在浏览器端执行,倒是给了我们开发者一个很好的位置去做只有浏览器端才做的逻辑,比如通过AJAX获取数据来填充组件的内容。在componentDidMount被调用的时候,组件已经被装载到DOM树上了,可以放心获取渲染出来的任何DOM

2.3.2 更新过程

  • 更新过程会依次调用下面的生命周期函数,其中render函数和装载过程一样,没有差别。□ componentWillReceiveProps□ shouldComponentUpdate□ componentWillUpdate□ render□ componentDidUpdate
  • ,每个React组件都可以通过forceUpdate函数强行引发一次重新绘制。

第3章 从Flux到Redux

3.1 Flux

3.1.1 MVC框架的缺陷

  • 不过这种状况逐渐在改变,因为越来越多的同行发现,在MVC中让View和Model直接对话就是灾难。

3.2 Redux

  • 我们把Flux看作一个框架理念的话,Redux是Flux的一种实现,除了Redux之外,还有很多实现Flux的框架,比如Reflux、Fluxible等,毫无疑问Redux获得的关注最多,这不是偶然的,因为Redux有很多其他框架无法比拟的优势。

3.2.1 Redux的基本原则

  • 如果状态数据分散在多个Store中,容易造成数据冗余,这样数据一致性方面就会出问题。虽然利用Dispatcher的waitFor方法可以保证多个Store之间的更新顺序,但是这又产生了不同Store之间的显示依赖关系,这种依赖关系的存在增加了应用的复杂度,容易带来新的问题。Redux对这个问题的解决方法就是,整个应用只保持一个Store,所有组件的数据源就是这个Store上的状态。
  • Reducer不是一个Redux特定的术语,而是一个计算机科学中的通用概念,很多语言和框架都有对Reducer函数的支持。就以JavaScript为例,数组类型就有reduce函数,接受的参数就是一个reducer, reduce做的事情就是把数组所有元素依次做“规约”,对每个元素都调用一次参数reducer,通过reducer函数完成规约所有元素的功能。

3.2.2 Redux实例

  • Redux中把存储state的工作抽取出来交给Redux框架本身,让reducer只用关心如何更新state,而不要管state怎么存

3.2.3 容器组件和傻瓜组件

  • 值得一提的是,拆分容器组件和傻瓜组件,是设计React组件的一种模式,和Redux没有直接关系

3.2.4 组件Context

  • Provider也是一个React组件,不过它的render函数就是简单地把子组件渲染出来,在渲染上,Provider不做任何附加的事情。
See all book notesSee all book notes