React

123 阅读1分钟

React


JSX


  • Js 和 XML 混合语法, 将 组件结构 数据 样式 聚合在一起的写法
  • 是一种语法糖,最终会通过babel转译成 React CreateElement
  • babel解析地址

cross-env DISABLE_NEW_JSX_TRANSFORM=true

React.createElement

  • 返回一个React元素
  • React元素事实上是个JS对象,用来描述视图内容
  • ReactDom 确保浏览器中真实DOM和React元素保持一致
  • 具体关系如下 源码实现

image.png

老的转换器 & 新的转换器

React.createElement(  type,  [props],  [...children])
  • 新的转换器作用,旧时由于编译后的代码用到了React,遍以前未用到React文件,但是需要提前引入
const babel = require("@babel/core");
const sourceCode = `<div className='title' style={{color: '#f00'}}>SanYeChunCha</div>`;
const result = babel.transform(sourceCode, {
    plugin: [['@babel/plugin-transform-react-jsx', { runtime: 'classic' }]]
})
console.log(result.code)
const result2 = babel.transform(sourceCode, {
    plugin: [['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }]]
})
console.log(result2.code)

虚拟dom组成

{
    $$typeof: Symbol(react.element), // 元素类型
    key: null, // 后面在DOM-diff处理元素移动,提高Diff性能
    ref: null, // 后面通过ref获取此虚拟DOM对应的真实DOM
    type: 'h1',
    props: {
        className: 'title',
        style: {...},
        children: '',
        type: 'h1'
    }
}

./react

import { REACT_ELEMENT } from './constant.js'
import { wrapToVdom } from './utils'

function createElement(type, config, children) {
    let ref, key;
    if(config) {
        ref = config.ref;
        key = config.key;
        delete config.ref;
        delete config.key;
        delete config.__source;
        delete config.__self;
    }
    let props = { ...config };
    if(arguments.length > 3) { // 多个儿子
        props.children = Array.prototype.slice.call(arguments, 2).map(wrapToVdom)
    }else { // 一个儿子
        props.children = wrapToVdom(children)
    }
    return {
        $$typeof: REACT_ELEMENT,
        type,
        key,
        ref,
        props
    }
}
const React = {
    createElement,
}

export default React

./constant

export const REACT_ELEMENT = Symbol('react.element');
export const REACT_TEXT = Symbol('react.text');

./utils

import { REACT_TEXT } from './constant';

/** 虚拟DOM 节点包装 */

export function wrapToVdom(element) {
    return typeof element === 'string' || typeof element === 'number' ? {
        type: REACT_TEXT, props: element
    }: element
}

组件

  • 组件有两种: 函数组件, 类组件
  • 类似于js function 接收任意props, 返回用于描述页面展示内容的react元素

函数组件

  • 组件名称大写字母开头
  • 在使用时 定义 或者 引用
  • 返回值只能有一个根元素

类组件