[转] react 是一个 js 框架, 类似于 jquery, 但是他做了很大的变化, 它将利用 jsx 语法, 将结构 (html) 和(js)合并在一起, 这里会有人好奇, 好不容易分离的, 为什么又和在一起了呢, 这是因为用脚本操作 dom 的代价很昂贵, 有个贴切的比喻, 把 DOM 和 JavaScript 各自想象为一个岛屿, 它们之间用收费桥梁连接, js 每次访问 DOM, 都要途径这座桥, 并交纳 "过桥费", 访问 DOM 的次数越多, 费用也就越高. 因此, 推荐的做法是尽量减少过桥的次数, 努力待在 ECMAScript 岛上. 因为这个原因 react 的虚拟 dom 就显得难能可贵了, 它创造了虚拟 dom 并且将它们储存起来, 每当状态发生变化的时候就会创造新的虚拟节点和以前的进行对比, 让变化的部分进行渲染. 整个过程没有对 dom 进行获取和操作, 只有一个渲染的过程, 所以 react 说是一个 ui 框架
1.react 组件化
react 组件很明显由 dom 视图和 state 数据组成, state 的状态决定着视图的状态, 这和 mvc 的开发有着区别, react 只负责 ui 的渲染, react 只根据 setState 来控制试图的更新, setState 会自动调用 render 函数, 触发试图的重新渲染, 组件就是拥有独立功能的视图模块, 许多小的组件合并成一个大的组件, 而整个页面也就是由不同的组件合并而成, 当我们是使用组件 < Hello/>其实是对 class Hello 的实例化, 相当于 new Hello()这里有三点需要注意 1. 组件的名字需要大写是为了区别 html 自己的标签, 也可以说成是区别内置组件 2. 由于 es6 中的 class 成为类的关键字, 所以样式部分 class 改为 className 3. 类和模块内部均采用严格模式, 所以不需要指定 use strict 运行模式
2.react 中的 diff 算法
当组件更新时候, react 会创建一个新的虚拟 dom, 并且会和之前存储的 dom 进行比较, 这个比较就是运用的 diff 算法, 所以组件的初始化使用不到该算法, react 提出一种假设, 相同的节点具有类似的结构, 不同的节点具有不同的结构, 在这种假设上进行逐层的比较, 如果发信啊对应的结点是不同的, 就直接删除原来的节点以及该节点包含的所有子节点, 然后替换成新节点, 如果是新节点则进行属性的更改, 而 patch 算法就是进行修改的算法
3. 组件的生命周期
理解该图很重要, 也就大致理解了 react 的工作原理, 当我们声明一个组件, 首先进行组件的初始化工作, 也就是在构造函数中, 将该有的数据初始化 (state),componentWillMount() 组件初始化时只调用, 以后组件更新不调用, 整个生命周期只调用一次, 此时可以修改 state, 然后 render()react 最重要的步骤, 创建虚拟 dom, 进行 diff 算法, 更新 dom 树都在此进行. 此时就不能更改 state 了, componentDidMount(), 组件渲染之后调用, 可以通过 this.getDOMNode()获取和操作 dom 节点, 只调用一次, shouldComponentUpdate(nextProps, nextState)react 性能优化非常重要的一环. 组件接受新的 state 或者 props 时调用, 我们可以设置在此对比前后两个 props 和 state 是否相同, 如果相同则返回 false 阻止更新, 因为相同的属性状态一定会生成相同的 dom 树, 这样就不需要创造新的 dom 树和旧的 dom 树进行 diff 算法对比, 节省大量性能, 尤其是在 dom 结构复杂的时候. 不过调用 this.forceUpdate 会跳过此步骤, componentWillUnmount()组件将要卸载时调用, 一些事件监听和定时器需要在此时清除
4.react-router 路由
Router 就是 React 的一个组件, 它并不会被渲染, 只是一个创建内部路由规则的配置对象, 根据匹配的路由地址展现相应的组件, Route 则对路由地址和组件进行绑定, 点击页面切换的过程变为当我点击 link 标签, 会先发生 url 的地址改变, 当 router 监听到地址改变, 就会根据 route 中的 path 去找匹配然后跳转到相应的 component, 另一个就是单页面应用, 当点击一个按钮切换到另一个部分应用的时候平时是需要向后台发送数据, 然后前台获得数据操作 dom, 而 react-router 只是按需加载相应的 js 文件到页面中
5. 组件之间的通信
react 推崇单项数据流, 自上而下进行数据的传递如果是父 ->子, 直接调用 props 属性, 如果是子 ->父则需要在父组件上设置回调函数当作属性传递给儿子, 儿子直接调用函数从而和父组件通信, 而兄弟之间无法直接通信, 他们只能利用同一层的上级作为中转, 状态提升, 传递信息
6.redux(这个目前还没用到, 啊哈哈, 先把解释贴着, 留给日后)
来源: http://www.jianshu.com/p/b683a9bac335