问题
<body>
<div id="root"></div>
</body>
import React from "react";
import ReactDOM from "react-dom";
function Bless() {
return (
<p>炸酱面加油</p>
<p>热干面加油</p>
)
}
ReactDOM.render(
<Bless />,
document.getElementById('root')
);
编译会报错:Adjacent JSX elements must be wrapped in an enclosing tag
。
解决方法
有3种解决方法。
第一种,HTML标签
比如,用<div>
包裹多个JSX元素并返回。
这个方法我不太喜欢,因为额外的<div>
在整个html结构中是几乎没有意义,它只会让结构变得臃肿。
function Bless() {
return (
<div>
<p>炸酱面加油</p>
<p>热干面加油</p>
</div>
)
}
第二种,数组
返回一个数组,数组元素是JSX元素。
这种方法不错的,不会添加额外的节点。
但是,请注意哈,如有必要,带上key
属性。
function Bless() {
// return [
// <div>炸酱面加油</div>,
// <p>热干面加油</p>
// ];
return (
[
<p key='p1'>炸酱面加油</p>,
<p key='p2'>热干面加油</p>
]
);
}
第三中,React.Fragment | <></>
最喜欢的就是这个方法了,不会添加额外节点,写得也顺手,就像写普通的标签一样。
<></>
是<React.Fragment></React.Fragment>
的语法糖,偷懒用的。
function Bless() {
return (
<React.Fragment>
<p>炸酱面加油</p>
<p>热干面加油</p>
</React.Fragment>
);
}
React.Fragment
和 javascript里的 文档片段 document.createDocumentFragment()
很类似,它们包裹的子内容会被插入文档DOM中,但本身不会。
<body>
<ul id="list">
</ul>
<script>
const fruits = ["apple","banana",'orange'];
const fragment = document.createDocumentFragment();
fruits.forEach(item => {
var li = document.createElement('li');
li.appendChild(document.createTextNode(item));
fragment.appendChild(li);
});
document.querySelector('#list').appendChild(fragment);
</script>
</body>
使用<React.Fragment>
时也请注意,如必要,请带上key
属性。
想偷懒用<></>
,但它不能带key
,有得就有失。
import React from "react";
import ReactDOM from "react-dom";
const dishes = [
{id:0,item:'鱼香肉丝',description:'鱼香肉丝里没有鱼'},
{id:1,item:'夫妻肺片',description:'夫妻肺片里没有肺'}
]
function Dishes(props){
return (
<dl>
{
props.dishes.map(dish => (
<React.Fragment key={dish.id}>
<dt>{dish.item}</dt>
<dd>{dish.description}</dd>
</React.Fragment>
))
}
</dl>
)
}
ReactDOM.render(
<Dishes dishes={dishes}/>,
document.getElementById('root')
);
dl:definition list
dt:definition item
dd:defition description