React原理
@ 姜波 | 星期二,七月 14 日,2020 年 | 3 分钟阅读 | 更新于 星期二,七月 14 日,2020 年

函数式编程

  • 一种编程范式,概念比较多
  • 纯函数
  • 不可变值

vdom和diff

同vue原理

http://wilberjiang.com/post/front/vue%E5%8E%9F%E7%90%86/

JSX本质

  • JSX等同于Vue模版

  • Vue模版不是html

  • JSX也不是JS

https://www.babeljs.cn/


// JSX 基本用法
const imgElem = <div id="div1">
    <p>some text</p>
    <img src={imgUrl}/>
</div>

// JSX style
const styleData = { fontSize: '30px',  color: 'blue' }
const styleElem = <p style={styleData}>设置 style</p>

// JSX 加载组件
const app = <div>
    <Input submitTitle={onSubmitTitle}/>
    <List list={list}/>
</div>

// JSX 事件
const eventList = <p onClick={this.clickHandler}>
    some text
</p>

// JSX list
const listElem = <ul>{this.state.list.map((item, index) => {
    return <li key={item.id}>index {index}; title {item.title}</li>
})}</ul>


// 总结
React.createElement('div', null, [child1, child2, child3])
React.createElement('div', {...}, child1, child2, child3)
React.createElement(List, null, child1, child2, '文本节点')
// h 函数
// 返回 vnode
// patch
  • React.createElement即h函数,返回vnode
  • 第一个参数,可能是组件,也可能是html tag
  • 组件名,首字母必须大写(React规定)

合成事件

  • 所有事件挂载到document上
  • event不是原生的,是SyntheticEvent合成事件对象
  • 和Vue事件不同,和DOM事件也不同

为何要合成事件机制

  • 更好的兼容性和跨平台
  • 挂载到document,减少内存消耗,避免频繁解绑
  • 方便事件的统一管理(如事务机制)

setState、batchUpdate

  • 有时异步(普通使用),有时同步(setTimeout、DOM事件)
  • 有时合并(对象形式),有时不合并(函数形式)

核心要点

  • setState主流程
  • batchUpdate机制
  • transaction(事务)机制

Image text

class ListDemo extends React.Component {
  constructor(props) {}
  render() {}
  increase = () => {
    // 开始:处于batchUpdate
    // isBatchingUpdates = true
    this.setState({
      count: this.state.count + 1
    })
    // 结束
    // isBatchingUpdates = false
  }
}

class ListDemo extends React.Component {
  constructor(props) {}
  render() {}
  increase = () => {
    // 开始:处于batchUpdate
    // isBatchingUpdates = true
    setTimeout(() => {
      // 此时isBatchingUpdates 是false
      this.setState({
        count: this.state.count + 1
      })
    })
    // 结束
    // isBatchingUpdates = false
  }
}

能命中batchUpdate机制

  • 生命周期(和它调用的函数)
  • React中注册的事件(和它调用的函数)
  • React可以“管理”的入口

不能命中batchUpdate机制

  • setTimeout、setInterval等(和它调用的函数)
  • 自定义的DOM事件(和它调用的函数)
  • React“管不到”的入口

transaction事务机制

Image text

transaction.initialize = function () {
  console.log("initialize")
}
transaction.close = function () {
  console.log("close")
}
function method() {
  console.log("abc")
}
transaction.perform(method)

// 输出“initialize”
// 输出“abc”
// 输出“close”

组件渲染/更新过程

渲染过程

  • props state
  • render()生成vnode
  • patch(elm,vnode)

更新过程

  • setState(newState)–>dirtyComponents(可能有子组件)
  • render()生成newVnode
  • patch(vnode,newVnode)

更新的两个阶段

上述的patch被拆分为两个阶段:

  • reconciliation阶段-执行diff算法,纯JS计算
  • commit阶段-将diff结果渲染DOM

可能会有性能问题:

  • JS是单线程,且和DOM渲染共用一个线程
  • 当组件足够复杂,组件更新时计算和渲染压力都大
  • 同时再有DOM操作需求(动画、鼠标拖拽等),将卡顿

解决方案fiber:

  • 将reconciliation阶段进行任务拆分(commit无法拆分)
  • DOM需要渲染时暂停,空闲时恢复
  • window.requestIdleCallback

公众号

Image text

QQ

Image text

微信

Image text

微信打赏

Image text

社交链接