JSX
简介
Facebook 的 React 团队在打造 React 战舰的时候同时也给战舰配备了刚健有力的外骨骼 JSX。从前面的文章中能发现,当我们需要创建复杂 DOM 树的时候,我们需要不断的 React.createElement() 元素与子元素,使用起来也显得格外麻烦,所以打造了类似于 HTML 和 XMl 一样易于阅读的 JSX。
我们先来打造一个周计划,尽可能的把JSX的一些常用语法点都囊括进去:
const weekPlanList = [
{
title: '周一的计划',
index: 1,
todoItems: [
{
index: 1,
time: '7:00 PM',
matters: '运动健身'
},
{
index: 2,
time: '9:00 PM',
matters: '阅读'
}
]
},
{
title: '周二的计划',
index: 2,
todoItems: [
{
index: 1,
time: '7:00 PM',
matters: '练习萨克斯'
},
{
index: 2,
time: '8:00 PM',
matters: '看一部电影'
}
]
},
{
title: '周三的计划',
index: 3,
todoItems: [
{
index: 1,
time: '7:00 PM',
matters: '练习毛笔字'
},
{
index: 2,
time: '8:00 PM',
matters: '短距离夜骑'
}
]
},
{
title: '周四的计划',
index: 4,
todoItems: [
{
index: 1,
time: '7:00 PM',
matters: '运动健身'
},
{
index: 2,
time: '8:00 PM',
matters: '高数学习'
}
]
},
{
title: '周五的计划',
index: 5,
todoItems: [
{
index: 1,
time: '7:00 PM',
matters: '云顶之奕'
}
]
},
{
title: '周六的计划',
index: 6,
todoItems: [
{
index: 1,
time: '7:00 AM',
matters: '绿道骑行'
},
{
index: 2,
time: '7:00 PM',
matters: '线代学习'
}
]
},
{
title: '周日的计划',
index: 7,
todoItems: [
{
index: 1,
time: '8:00 AM',
matters: '学习,整理,总结'
},
{
index: 2,
time: '3:00 PM',
matters: '追番,追剧,追综艺'
}
]
}
];
// 每日待办的函数组件
const TodoItems = ({ todoItems }) => (
<>
<ul>
{todoItems.map(item => (
{ /* 定义标签 class 属性时,JSX 中要用 className,因为 class 是 JavaScript 声明 类的保留字 */ }
<li clsssName="todo-item" key={item.index}>{`${item.time}:${item.matters}` }</li>
)
)}
</ul>
</>
);
// 周计划的函数组件
const WeekPlan = (weekPlanList) => (
{weekplanList.map(weekplan => (
<React.Fragment key={weekplan.index}>
<h2>{weekplan.title.replace('的', '') + ':'}</h2>
<TodoItems {...weekplan} />
</React.Fragment>
)
)}
);
// 渲染 DOM
ReactDOM.render(
<WeekPlan weekPlanList={weekPlanList} />,
document.getElementById('root')
);
1. JavaScript 表达式
JSX 中 JavaScript 表达式放在大括号内,可以是一个变量也可以是变量的拼接或加减,甚至是表达式内的函数也会被调用,可以看到 WeekPlan 组件 <h2> 标签中的表达式就是一个 函数的调用并进行了字符串的拼接。
2. 组件嵌套
JSX 可以把组件添加作为组件的子元素。在 WeekPlan 组件中,我们嵌套了 TodoItems 每日待办组件,也就是,组件直接当标签用。
3. JSX 代码注释
如上代码,我们对 class 属性 用 className 代替的解释,就是用的代码注释方法 *{/ */}**, 还有一种单行注释为 {// ... }。
4. 数组映射
JSX 中数组映射: 直接将数组映射为JSX元素,常用到的方法: Array.map 。上边的两个函数组件中也有体现。在数组映射的时候,我们会给元素绑定一个key属性,在日常的业务代码中,可能根本用不上这个属性,但是这个属性尤其重要,在讲这个属性之前,我们来聊聊电视剧。
最近在看《潜行者》时,黄晓明饰演的方嘉树,在军统地下党,共产党潜伏者,76号副处长这三个组织关系处理得游刃有余,我记得只有共产党的潜伏者的上下线联络的时候,用的是暗号对接,我猜测哈,用暗号对接,估计可能是比较安全,还有一个可能就是"太穷"了吧,但也因为他们这么多的英雄们,也才有了现在的这整个社会…感恩感谢!
哈哈哈,中途插了个电视广告,我们要说的这个 key 就是 props 携带的属性 与 DOM 元素间对接的暗号。也就是说,上线 props 要行动, 通过"暗号" key 快速通知下线 DOM 作出相应的行动。
5. Fragment 碎片化节点
React,Vue 都不能在一个组件中渲染两个或两个以上的同辈或同级元素,必须要把这些标签放在一个标签内,比如 div, Vue2.x 就只能这样处理。这种情况对上面的周计划组件就相当难受,好在 Vue3.x 和 React 都提供了 Fragment。
Fragment:可以模拟容器的行为,但不会创建真正的标签
我们在中计划组件中用到了 <React.Fragment> 标签,就是为了解决碎片化节点的渲染问题。我们在待办组件中看到一个 <></>空标签,这个空标签其实就是 <React.Fragment>的精简代码,这样易于编写。
当然这两者的用处还是有所区别的,当我们在做数据映射时,需要绑定属性值时,就必须要用<React.Fragment>,只有在只是作为一个容器标签时才可以简写。在实际的开发中,TodoItems 组件中的空标签是没有必要写的,这里只是作为一个例子进行讲解用到。
总结
来回忆一下,这篇文章讲了些啥?
- JSX:是由 Facebook 的 React 团队创建的类似于 HTML,XML 的代码格式;
- JavaScript 表达式:
{}中可以赋值,也可以添加计算,串联,甚至可以调用函数;- className 属性:对应的是 DOM 标签中的 class 属性;
- 嵌套组件:一个组件可以作为另一个组件可以重复引用的子元素;
- 数据映射:
{}中,可将数据映射为 JSX 元素,key 属性具有关联性,常用的数据映射方法 Array.map;- JSX 代码注释: 多行
{/* */},单行{// };- Fragment 标签:一个多根元素标签容器,不会被渲染出对应的标签,简写为
<></>,需要绑定属性时,只能用<React.Fragment>标签。