您好,欢迎访问一九零五行业门户网

Diff算法的分析:利用React渲染流程分析

本篇文章给大家带来的内容是关于diff算法的分析:利用react渲染流程分析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
1、什么是虚拟dom在react中,render执行的结果得到的并不是真正的dom节点,结果仅仅是轻量级的javascript对象,我们称之为virtual dom。简单的说,其实所谓的virtual dom就是javascript对象到html dom节点的映射;即使用javascript对象将html结构表示出来,而这个对象就是virtual dom。
html:
<ul id='list'>  <li class='item'>item 1</li>  <li class='item'>item 2</li></ul>
javascript对象表示(virtual dom)
{  tagname: 'ul',  props: {    id: 'list'  },  children: [    {tagname: 'li', props: {class: 'item'}, children: [item 1]},    {tagname: 'li', props: {class: 'item'}, children: [item 2]},  ]}
2、什么时候会生成到virtual domreact生命周期拥有装载、更新、卸载的三个阶段;附上一张react生命周期图
前面提到:render执行的结果得到的并不是真正的dom节点,结果仅仅是轻量级的javascript对象,即在render函数调用时将会创建出虚拟dom;
class tab extends react.component {    render() {        react.createelement(          'p',          { classname: 'class'},          'hello react'        )    }}
通过react.createelemen创建出虚拟dom,而该函数只在render函数中调用,所以在react装载和更新的过程中才会有虚拟dom的生成;至于挂载到真实dom自然而然是reactdom.render函数啦。
3、virtual dom如何实现实现其实很简单,主要是定义一个函数并把我们传进去的参数组成一个react元素对象,而type就是我们传进去的组件类型,可以是一个类、函数或字符串(如'p')
react大致源码:
function createelement(type, config, children) {  let propname;  const props = {};  let key = null;  let ref = null;  let self = null;  let source = null;  if (config != null) {    if (hasvalidref(config)) {      //  如果有ref,将它取出来      ref = config.ref;    }    if (hasvalidkey(config)) {      //  如果有key,将它取出来      key = '' + config.key;    }    self = config.__self === undefined ? null : config.__self;    source = config.__source === undefined ? null : config.__source;        for (propname in config) {      if (        hasownproperty.call(config, propname) &&        !reserved_props.hasownproperty(propname)      ) {        //  将除ref,key等这些特殊的属性放到新的props对象里        props[propname] = config[propname];      }    }  }  //  获取子元素  const childrenlength = arguments.length - 2;  if (childrenlength === 1) {    props.children = children;  } else if (childrenlength > 1) {    const childarray = array(childrenlength);    for (let i = 0; i < childrenlength; i++) {      childarray[i] = arguments[i + 2];    }    props.children = childarray;  }  //  添加默认props  if (type && type.defaultprops) {    const defaultprops = type.defaultprops;    for (propname in defaultprops) {      if (props[propname] === undefined) {        props[propname] = defaultprops[propname];      }    }  }    return reactelement(    type,    key,    ref,    self,    source,    reactcurrentowner.current,    props,  );}const reactelement = function(type, key, ref, self, source, owner, props) {  //  最终得到的react元素  const element = {    // this tag allows us to uniquely identify this as a react element    $$typeof: react_element_type,    // built-in properties that belong on the element    type: type,    key: key,    ref: ref,    props: props,    // record the component responsible for creating this element.    _owner: owner,  };  return element;};
打印出组件:
4、为什么需要使用virtual domdom管理历史阶段:
js 或者 jquery 操作 dom: 当应用程序越来越复杂,需要在js里面维护的字段也越来越多,需要监听事件和在事件回调用更新页面的dom操作也越来越多,应用程序会变得非常难维护。
后来产出 mvc、mvp 的架构模式,期望从代码组织方式来降低维护难度。但是 mvc 架构并没办法减少维护的状态,也没有降低状态更新时需要对页面的更新操作,你需要操作的dom还是需要操作,只是换了个地方。
既然状态改变了要操作相应的dom元素,为什么不做一个东西让视图和状态进行绑定,状态变更了视图自动变更。这就是后来人们想出了 mvvm 模式,只要在模版中声明视图组件是和什么状态进行绑定的,双向绑定引擎就会在状态更新的时候自动更新视图;
但mvvm双向数据绑定并不是唯一的办法,还有一个非常直观的方法:一旦状态发生了变化,就用模版引擎重新渲染整个视图,然后用新的视图更换掉旧的视图。
react采用的就是第四种模式;但是我们都知道对于操作dom成本太高,而相对操作javascript就快速多了,而html dom可以很简单的用javascript对象表示出来(virtual dom就这样诞生了)
这样的做法会导致很多的问题,最大的问题就是这样做会很慢,因为即使一个小小的状态变更都要重新构造整棵 dom,性价比太低;而react virtual dom在状态更新过程加了一些特别的操作来避免整棵 dom 树变更。
相关推荐:
以上就是diff算法的分析:利用react渲染流程分析的详细内容。
其它类似信息

推荐信息