一、JSX
1、什么是JSX
- Facebook起草的JS扩展语法
- 本质是一个JS对象,会被babel编译,最终会被转换为React.createElement
const h1 = <h1>hello world <span>span</span></h1>;
ReactDOM.render(h1, document.getElementById("root"));
实际是因为babel将jsx编译成了React.cloneElement(它是一个对象形式)
(<h1>hello world <span>span</span></h1>); //用(),防止忘记书写;和其他表达式混合
||
||
React.cloneElement("h1",{},"hello world", React.cloneElement("span",{},"span"));
- 每个JSX表达式,有且仅有一个根节点
通过前面,我们知道jsx被babel变异成React.cloneElement,但是如果你有两个根节点,那就无法编译成功了!
const h1 = (
<h1>hello world <span>span</span></h1>
<p>p</p>
);
那么如果某些情况下我们必须要要多个根节点呢?
方法一:
外层嵌套一个父节点
const h1 = (
<div>
<h1>hello world <span>span</span></h1>
<p>p</p>
</div>
);
方法二:
如果也不想外层嵌套一个父节点。
const h1 = (
<>
<h1>hello world <span>span</span></h1>
<p>p</p>
</>
);
const h1 = (
<React.Fragment>
<h1>hello world <span>span</span></h1>
<p>p</p>
</React.Fragment>
);
- 每个JSX元素必须结束(XML规范)
可以是类似<img />
自结束。
2、在JSX中嵌入表达式
const a = 123, b = 321;
const div = (
<div>
{a}*{b}={a*b}
</div>
);
ReactDOM.render(div, document.getElementById("root"));
实际这里的编译过程
const div = (
<div>
{a}*{b}={a*b}
</div>
);
||
||
const div = React.createElement("div",{},`${a}*${b}=${a*b}`);
- 在JSX中使用注释
使用ctrl+/
即可
{/* <p></p> */}
- 将表达式作为内容的一部分
1、null、undefined、false不会显示**
const a = 123, b = 321;
const div = (
<div>
{a}*{b}={a*b}
<p>
{null}
{undefined}
{false}
</p>
</div>
);
ReactDOM.render(div, document.getElementById("root"));
2、普通对象,不可以作为子元素
const a = 123, b = 321;
const obj = {c:2};
const div = (
<div>
{a}*{b}={a*b}
<p>
{obj}
</p>
</div>
);
ReactDOM.render(div, document.getElementById("root"));
3、可以放置React元素对象
const a = 123, b = 321;
const obj = <span>span</span>;
const div = (
<div>
{a}*{b}={a*b}
<p>
{obj}
</p>
</div>
);
如果是数组,会遍历数组将子元素加入
const a = 123, b = 321;
const arr = [1,2,3,4];
const div = (
<div>
{a}*{b}={a*b}
<p>
{arr}
</p>
</div>
);
- 将表达式作为元素属性
const url = '*****';
const div = (
<div>
<img src={url} alt=""/>
</div>
);
- 属性使用小驼峰命名法
const url = '*****';
const cls = 'image';
const div = (
<div>
<img src={url} className={cls} alt=""/>
</div>
);
这里的style{{}},外一层是表示分界,里面的是一个对象
const url = '*****';
const cls = 'image';
const div = (
<div>
<img src={url} className={cls} style={{
width: '200px',
height: '100px',
border: '1px solid #eee'
}} alt=""/>
</div>
);
- 防止注入攻击
1、自动编码
会自动编码成纯文本
const content = '<script>*****</script>';
const div = (
<div>
{content}
</div>
);
2、dangerouslySetInnerHTML
如果不需要编码,可以使用dangerouslySetInnerHTML
const content = '<script>*****</script>';
const div = (
<div dangerouslySetInnerHTML={{
__html: content
}}>
</div>
);
3、元素的不可变性
- 虽然JSX元素是一个对象,但是该对象中的所有属性不可更改
- 如果确实需要更改元素的属性,需要重新创建JSX元素
因为这里它使用了Object.freeze(data)
,冻结对象,只读;如果实在需要的话,可以重新创建jsx。
setInterval(() => {
num++;
const div = (
<div title="asdfadf">
{num}
</div>
);
ReactDOM.render(div, document.getElementById("root"));
}, 1000);
这里的性能不用担心,它只会改变dom内变化的内容,不会从新生成新的div
博主开始运营自己的公众号啦,感兴趣的可以关注“飞羽逐星”微信公众号哦,拿起手机就能阅读感兴趣的博客啦!