react核心功能实现

react核心功能实现

前言

react核心其实挺多的,但面试能说上元素创建和基本渲染过程基本就算合格。
而在此基础上,能说清楚diff算法的三层比较策略,15.x的递归不可打断更新和
16.x以后的循环可打断更新,又是一波加分项。

本篇为源码系列核心实现第七篇,对应下图react部分。

src

本篇不会像之前的那些细致化的去写,因为我发现了一个写的十分优秀的库,就不献丑了。

createElement

大道至极,这个其实就是虚拟dom,一个用于描述真实dom结构的js对象。


function createElement( tag, attrs={
    
    }, ...children ) {
    
    
    return {
    
    
        tag,
        attrs,
        children,
    }
}



render

render做了很多事,但最主要的是把上边创建的虚拟dom转化成真实dom。
当然,这之中还会涉及事件绑定,样式处理,diff算法什么的,这里只做一个简化展示。


function render( vnode, container ) {
    
    
    
    // 当vnode为字符串时,渲染结果是一段文本
    if ( typeof vnode === 'string' ) {
    
    
        const textNode = document.createTextNode( vnode );
        return container.appendChild( textNode );
    }

    const dom = document.createElement( vnode.tag );

    if ( vnode.attrs ) {
    
    
        Object.keys( vnode.attrs ).forEach( key => {
    
    
            const value = vnode.attrs[ key ];
             setAttribute( dom, key, value );    // 设置属性
        } );
    }
    // 递归渲染子节点
    vnode.children.forEach( child => render( child, dom ) );  
    // 将渲染结果挂载到真正的DOM上
    return container.appendChild( dom );   
}


function setAttribute( dom, name, value ) {
    
    
    // 如果属性名是className,则改回class
    if ( name === 'className' ) name = 'class';
    // 如果属性名是onXXX,则是一个事件监听方法
    if ( /on\w+/.test( name ) ) {
    
    
        name = name.toLowerCase();
        dom[ name ] = value || '';
    // 如果属性名是style,则更新style对象
    } else if ( name === 'style' ) {
    
    
        if ( !value || typeof value === 'string' ) {
    
    
            dom.style.cssText = value || '';
        } else if ( value && typeof value === 'object' ) {
    
    
            for ( let name in value ) {
    
    
                // 可以通过style={ width: 20 }这种形式来设置样式,可以省略掉单位px
                dom.style[ name ] = typeof value[ name ] === 'number' ?
                 value[ name ] + 'px' : value[ name ];
            }
        }
    // 普通属性则直接更新属性
    } else {
    
    
        if ( name in dom ) {
    
    
            dom[ name ] = value || '';
        }
        if ( value ) {
    
    
            dom.setAttribute( name, value );
        } else {
    
    
            dom.removeAttribute( name );
        }
    }
}


相关链接

再会

情如风雪无常,

却是一动既殇。

感谢你这么好看还来阅读我的文章,

我是冷月心,下期再见。

猜你喜欢

转载自blog.csdn.net/qq_42813491/article/details/113848454