组件化和React
- 对组件化的理解?
- JSX 的本质是什么?
- JSX 和 vdom
- setState 的过程?
- React 和 Vue 有什么异同?
组件化
- 组件的封装
组建个的封装包括封装视图、数据、变化逻辑[数据驱动视图]。
类似于面向对象[封装、集成、多态]的思想。 组件的复用
- props 传值
- 复用
class List extends Component { render () { const list = this.props.data return ( <ul> { list.map((item, index) => { return <li key={index}>{item}</li> }) } </ul> ) } }
import List from "List"; class Todo extends Component { constructor (props) { this.state = { list: [] } } render () { return ( <div> <List data={this.state.list}/> <List data={this.state.list}/> <List data={this.state.list}/> </div> ) } }
jsx 的本质
jsx 只是语法糖,需要转换成 js 才能在浏览器运行。
jsx 的语法:
- {} 中书写 js 的表达式或者变量
- 标签:支持所有的 HTML 标签和自定义组件名称
jsx 是怎么运行的?
- React.createElement
React.createElement(标签名,属性,子标签1,子标签2,...)
React.createElement(标签名,属性,[子标签数组])
React.createElement 返回 vnode,类似于 vue 中的 _c 函数,snabbdom 中的 h 函数。
jsx 独立标准
jsx 是 React 引入的,但并不是独有的。
React 将 jsx 作为独立标准开放,解析 jsx 用的 React.createElement 是可以修改的。
什么是标准化?
功能完善。
和其它标准兼容,扩展没有问题。
jsx 的解析
jsx 的编译器只会处理 “HTML” 标签,不会处理注释。
npm 安装 transform-react-jsx
包,使用 babel --plugin transform-react-jsx xx.jsx
可以查看编译后的文件。
在首行添加注释 /* @jsx h */
可以将默认的 React.createElement
替换成 h
函数解析 jsx。
jsx 和 vdom
vdom 伴随 React 而生,由 React 推广开来。
为什么需要 vdom ?
真实的 dom 节点 node 的属性很多,vnode 仅仅实现一些必要的属性,创建一个 vnode 的成本较低。
使用 vnode 让一次数据变动带来所有 node 的变化,先在 vnode 中进行修改,然后 diff 之后对所有产生差异的节点集中一次对 dom tree 进行修改,以减少浏览器的重绘及回流。
- jsx 需要转换成 js 代码
- jsx 解析返回 vnode
h 函数和 React.createElement 的区别:h 函数的第一个参数是 HTML 标签;React.createElement 的第一个参数可以是 HTML 标签,也可以是自定义组件的名称。
jsx 什么时候执行 patch ?
- 初次渲染
ReactDOM.render(<App/>, container)
,会触发patch(container, vnode)
- rerender
setState
,会触发patch(vnode, newVnode)
setState 的过程
setState 是异步的
vue 的属性修改也是异步的。
addTitle (title) { const currentList = this.state.list console.log(this.state.list) // ['a', 'b'] this.setState({ list: currentList.concat(title) }) console.log(this.state.list) // ['a', 'b'] }
setState 为什么要使用异步?
- 可能一次执行多个 setState
- setState 是开放的,无法限制或规定用户如何使用 setState
- 考虑性能,没有必要每次 setState 都重新渲染一次
- 即使重新渲染,用户也看不到中间的效果【js 执行和 dom 渲染是阻塞的】
vue 的实现流程
- 解析模板成 render 函数
- 响应式开始监听
- 首次渲染,显示页面,且绑定依赖
- data 属性变化,触发 rerender
data 属性变化,会被 set 监听到(非异步),set 会执行 updateComponent 函数(异步),进行rerender
setState 的过程
- 每个组件实例都有 renderComponent 方法
- 执行 renderComponent 会重新执行实例的 rerender
- rerender 函数返回 newVnode,然后会拿到 prevVnode
- 执行 patch(prevVnode, newVnode)
React 和 Vue 的对比
- 本质区别
- vue:本质是 MVVM 框架,由 MVC 发展而来
- React:本质是前端组件化,由后端组件化(如 smarty)发展而来
- 模板区别
- vue:使用的模板由 angular 提出
- React:使用jsx
模板语法上,更倾向于 jsx [vue 在模板语法上由学习成本,jsx 只需要知道 {} 内写 js 即可]
模板分离上,更倾向于 vue [jsx 将模板和逻辑(js)混在一起,没有遵循开放封闭原则(对扩展开放,对修改封闭)]
- 组件化的区别
- vue:使用的组件化是在 MVVM 的基础上的扩展
- React:本身就是组件化,没有组件化就不是 React
- 共同点
- 都支持组件化
- 都是数据驱动视图