首先我们写的jsx语法,是用声明式的方式把React中的React.createElement简化,也就是一种语法糖。用代码举例子。
1.简单例子
const element = (
<div style={{ backgroundColor: 'red' }}>
我我我
<button onClick={() => console.log('点击')}>点我</button>
</div>
)
这是声明式,我们直接声明一个类型div的React元素,属性有style,children,children包含一个字符串和一个类型为按钮,属性有onClick,children,React元素这样的一个声明。babel会帮我们转变为命令式代码。
const element = React.createElement(
'div',
{ style: { backgroundColor: 'red' } },
'我我我',
React.createElement(
'button',
{ onClick: () => console.log('点击') },
'点我'
)
)
这和上面的等价的,createElement三个参数(属性),type,props,children。然后调用这个方法生成虚拟DOM对象。参数对应的就是返回值对象中的属性。
{
type: 'div',
props: {
style: { backgroundColor: 'red' },
children: [
'我我我',
{
type: 'button',
props: {
onClick: [Function],
children: '点我'
}
}
]
}
}
返回值实际上是这个样子的。我们写组件其实和这个过程一样的。
2.组件例子
首先我们搞一个父组件。
import React from 'react'
import Item from '../Item'
export default function List() {
const state = [1, 2]
const a = Item()
console.log(a);
return (
<div style={{ backgroundColor: 'red' }}>
{
state.map((index) => {
return (<Item key={index} />)
})
}
</div>
)
}
实际上返回的就是jsx,安装的babel帮我们转化为命令式。这里的父子组件的结构就是
<div>
<Item/>
<Item/>
</div>
转化为命令式参数有type:div,props:{ children,style},key:null
然后子组件
import React from 'react'
export default function Item() {
const handle = () => {
console.log(' 1', 1)
}
return (
<div>
我我我
<button onClick={handle}>点我</button>
</div>
)
}
子组件转化为命令式参数有key:1/2 props:{children onClick} type:div
然后我们组件在调用命令式方法的时候就是转化为虚拟DOM
const Listobj = {
key: null,
props: {
children: [{
key: 0,
props: {
children: ['我我我', {
key: null,
props: {
onClick: () => {
console.log('1', 1)
},
children: '点我'
},
type: 'buttom'
}],
},
type: 'div'
}, {
key: 1,
props: {
children: ['我我我', {
key: null,
props: {
onClick: () => {
console.log('1', 1);
},
children: '点我'
},
type: 'button'
}],
},
type: 'div'
}],
style: { backgroundColor: 'red' }
},
type: 'div'
}
虚拟DOM大概就是这样,然后调用render之后把虚拟DOM对象里面的属性用原生DOM去引用,创建真实DOM元素,这是React框架帮我们做的。现在先不去理解这些