美文网首页web前端
拜读Preact源码有感

拜读Preact源码有感

作者: 侬姝沁儿 | 来源:发表于2019-01-28 14:27 被阅读26次

    jsx本质

    JSX是一种嵌入式的类似XML的语法,它可以被转换成合法的JavaScript,转换的语义是依据不同的实现而定的。例如react有react的jsx语法和转换器babel-plugin-transform-react-jsx ,vue有vue的jsx语法和转换器babel-plugin-transform-vue-jsx,当然,这也意味你可以开发自己的jsx语法和转换器jsx

    react本质

    babel-plugin-transform-react-jsx

    react通过babel-plugin-transform-react-jsx将jsx语法转换为可以被React.createElement识别的形式,即:

    <div id="foo" name="bar">Hello!</div>
    
    // 转换为
    
    React.createElement('div', { id: 'foo', name : 'bar' }, 'Hello!');
    

    也就是说,react的jsx只是React.createElement的语法糖而已,我们看起来在写jsx,实际上babel-plugin-transform-react-jsx已经将我们写的jsx语法转换了。

    React.createElement

    jsx语法被转换器转换后,变成可以被React.createElement所识别的内容。React.createElement(component, props, ...children) 则将能识别的相应内容解析为虚拟DOM。

    React.createElement('div', { id: 'foo', name : 'bar' }, 'Hello!');
    
    // 转换为
    
    {
      $$typeof: Symbol(react.element),
      key: null,
      props: {id: "foo", name: "bar", children: "Hello!"},
      ref: null,
      type: "div",
      _owner: {},
      _store: {}
    }
    

    虚拟DOM的本质:(virtual-dom)

    虚拟DOM从本质上将就是将复杂的DOM转化成轻量级的JavaScript对象,不同的渲染中却会生成同样的虚拟DOM对象,然后通过高效优化过的Diff算法,比较前后的虚拟DOM对象,以最小的变化去更新真实DOM。

    {
      $$typeof: Symbol(react.element),
      key: null,
      props: {id: "foo", name: "bar", children: "Hello!"},
      ref: null,
      type: "div",
      _owner: {},
      _store: {}
    }
    
    // Hello 变为 Hello react
    
    {
      $$typeof: Symbol(react.element),
      key: null,
      props: {id: "foo", name: "bar", children: "Hello react!"},
      ref: null,
      type: "div",
      _owner: {},
      _store: {}
    }
    

    对比对象我们可以看到,只有 props.children 发生了变化,利用高效的对比diff方法找到不同,并把不同的内容修改,进行一个真实dom上的映射改变。即:

    <div id="foo" name="bar">Hello!</div>
    
    // dom映射后
    
    <div id="foo" name="bar">Hello react!</div>
    

    结语

    即react的核心思想就是利用jsx转换器,将jsx转换为React.createElement能理解的形式,然后React.createElement又将相应内容解析为虚拟DOM。不同的渲染中却会生成同样的虚拟DOM对象,然后通过高效优化过的Diff算法,比较前后的虚拟DOM对象,最后通过dom的相应方法以最小的变化去更新真实DOM。无外乎是:jsx组件到虚拟DOM的转化、以及虚拟DOM到真实DOM的映射。

    相关文章

      网友评论

        本文标题:拜读Preact源码有感

        本文链接:https://www.haomeiwen.com/subject/fmeajqtx.html