React入门(一)

JSX(JAVASCRIPT AND XML[HTML])语法

  • ReactDOM.render([JSX],[container],[callback]):把JSX元素渲染在页面
    // 不建议把JSX直接渲染在BODY中,但是可以这么干
    ReactDOM.render(
    Hello world!
    ,document.body, () => { console.log(1); })
  • JSX中的{ }存放的是JS表达式,不能直接放入对象数据类型的值(除不含对象的数组和几种特殊情况外:style设置成对象值才行,例如style={{color:'red'}}
    let obj = {name:"leonard"};
    // Uncaught Error: Objects are not valid as a React child
    ReactDOM.render(<>
        {obj}    
    , document.getElementById('root'));
    
  • nullundefined代表空元素,什么也不显示
    ReactDOM.render(<>
      {null}    // nothing
    , document.getElementById('root'))
    
  • 数组遍历(需要给创建元素设定唯一的key值)
    let arr = [10,20,30];
    ReactDOM.render(
    {arr.map(item=>{ return {item} })}
    , document.getElementById('root'));
  • 样式类名是className而不是class

模拟实现虚拟DOM转换为真实DOM

  • 虚拟DOM转换为真实DOM的过程
    1.基于babel-preset-react-app把JSX变为React.createElement()
    React.createElement()中的参数含义:
        第一项为标签名(或者组件名)
        第二项为给标签设置的属性,此项为空则显示为null
        第三项或者更多项:标签的子节点
    2.执行React.createElement()创建虚拟DOM对象
    3.ReactDOM.render(JSX生成的对象,容器,回调函数)把虚拟DOM对象变为真实的DOM对象(渲染到页面中)
  • 代码实现
export function createElement(type, props, ...childrens) {
    let ref, key;
    if ('ref' in props) {
        ref = props['ref'];
        props['ref'] = undefined;
    }
    if ('key' in props) {
        key = props['key'];
        props['key'] = undefined;
    }
    return {
        type,
        props: {
            ...props,
            children: childrens.length <= 1 ? (childrens[0] || '') : childrens
        },
        ref,
        key
    };
}

export function render(objJSX, container, callBack) {
    let {type, props} = objJSX,
        {children} = props;
    let newElement = document.createElement(type);
    for (let attr in props) {
        if (!props.hasOwnProperty(attr)) break;
        let value = props[attr];
        if (value == undefined) continue; // NULL OR UNDEFINED
        switch (attr.toUpperCase()) {
            case 'CLASSNAME':
                newElement.setAttribute('class', value);
                break;
            case 'STYLE':
                for (let styleAttr in value) {
                    if (value.hasOwnProperty(styleAttr)) {
                        newElement['style'][styleAttr] = value[styleAttr];
                    }
                }
                break;
            case 'CHILDREN':
                !(value instanceof Array) ? value = [value] : null;
                value.forEach((item, index) => {
                    if (typeof item === 'string') {
                        let text = document.createTextNode(item);
                        newElement.appendChild(text);
                    } else {
                        render(item, newElement);
                    }
                });
                break;
            default:
                newElement.setAttribute(attr, value);
        }
    }
    container.appendChild(newElement);
    callBack && callBack();
}

你可能感兴趣的:(React入门(一))