JSX
{}可以渲染出来的值
- 原始值类型:只渲染字符串/数字,其余的值都会渲染为空
- 对象类型:
- 数组对象:可以进行渲染,而且不是转换为字符串(每一项之间没有逗号分隔),它会逐一迭代数组每一项,把每一项都拿出来单独进行渲染!!
- 函数对象:可以做为函数组件进行渲染,但是要写成 这种格式
- 其它对象:一般都是不可以直接进行渲染的
- 可以是一个jsx对象
- 如果设置的是style样式,则样式值必须写为对象格式
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<>
<div className="box">{name}</div>
<div style={{
color: 'red',
fontSize: '14px'
}}>
{num > 10 ? 'OK' : 'NO'}
</div>
<ul>
{arr.map(item => {
let { id, title } = item;
return <li key={id}>
{title}
</li>;
})}
</ul>
{Reflect.ownKeys(obj).map((key, index) => {
let val = obj[key];
return <span key={index}>
{key} : {val}
</span>
})}
</>
);
JSX底层渲染机制
createElement
const createElement = function createElement(type, props, ...children) {
// virtual:[ˈvɜːtʃuəl]
let len = children.length;
let virtualDOM = {
type,
props: {}
};
if (props !== null) virtualDOM.props = { ...props };
if (len === 1) virtualDOM.props.children = children[0];
if (len > 1) virtualDOM.props.children = children;
return virtualDOM;
};
render
const render = function render(virtualDOM, container) {
let { type, props } = virtualDOM;
if (typeof type === "string") {
let element = document.createElement(type);
for (let key in props) {
if (!props.hasOwnProperty(key)) break;
if (key === 'className') {
element.setAttribute('class', props[key]);
continue;
}
if (key === 'style') {
let styOBJ = props['style'];
for (let attr in styOBJ) {
if (!styOBJ.hasOwnProperty(attr)) break;
element.style[attr] = styOBJ[attr];
}
continue;
}
if (key === 'children') {
let children = props['children'];
if (!Array.isArray(children)) children = [children];
children.forEach(item => {
if (typeof item === "string") {
element.appendChild(document.createTextNode(item));
return;
}
render(item, element);
});
continue;
}
element.setAttribute(key, props[key]);
}
container.appendChild(element);
}
};