使用JSX书写标签语言
JSX是JavaScript语法扩展,可以让你在JavaScript文件中书写类似HTML的标签。虽然还有其它方式可以编写组件,但大部分React开发者更喜欢JSX的简洁性,并且在大部分代码库中使用它。
你将会学习到
-为什么React将标签和渲染逻辑耦合在一起
-JSX和HTML有什么区别
-如何通过JSX展示信息
JSX:将标签引入JavaScript
网页时构建在HTML、CSS和JavaScript之上的。多年以来,web开发者都是将网页内容放在HTML中,样式放在CSS中,而逻辑则放在JavaScript中--通常是在不同的文件中!页面的内容通过标签语言描述并存放在HTML文件中,而逻辑则单独存放在JavaScript文件中。

但随着web的交互性越来越强,逻辑越来越决定页面中的内容。JavaScript控制着HTML的内容!这也是为什么在React中,渲染逻辑和标签共同存在于同一个地方--组件。

将一个按钮的渲染逻辑和标签放在一起可以确保它们在每次编辑时都能保持互相同步。反之,彼此无关的细节是互相隔离的,例如按钮的标签和侧边栏的标签。这样我们在修改其中任意一个组件时会更安全。
每个React组件都是一个JavaScript函数,它会返回一些标签,React会将这些标签渲染到浏览器上。React组件使用一种被称为JSX的语法扩展来描述这些标签。JSX看起来和HTML很像,但它的语法更加严格并且可以动态展示信息。了解这些区别最好的方式就是将一些HTML标签转化为JSX标签。
JSX and React是相互独立的东西。但它们经常一起使用,但你可以单独使用它们中的任意一个,JSX是一种语法扩展,而React则是一个JavaScript的库。
将HTML转化为JSX
假设你现在有一些(完全有效)的HTML标签:
| <h1>海蒂·拉玛的待办事项</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" > <ul> <li>发明一种新式交通信号灯 <li>排练一个电影场景 <li>改进频谱技术 </ul> |
而现在想要把这些标签迁移到组件中:
| export default function TodoList() { return ( // ??? ) } |
如果直接复制到组件中,并不能正常工作:
| export default function TodoList() { return ( // 这不起作用! <h1>海蒂·拉玛的待办事项</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" > <ul> <li>发明一种新式交通信号灯 <li>排练一个电影场景 <li>改进频谱技术 </ul> ); } |
提示异常:
| Error /src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (5:4) 3 | // 这不起作用! 4 | <h1>海蒂·拉玛的待办事项</h1> > 5 | <img | ^ 6 | src="https://i.imgur.com/yXOvdOSs.jpg" 7 | alt="Hedy Lamarr" 8 | class="photo" |
这是因为JSX语法更加严格并且相比HTML有更多的规则!上面的错误提示可以帮助你修复标签中的错误,当然也可以参考下面的指引。
注意:大部分情况下,React在屏幕上显示的错误提示就能帮你找到问题所在,如果在编写过程中遇到问题就参考一下提示把。
JSX规则
- 只能返回一个根元素
如果想要在一个组件中包含多个元素,需要用一个父标签把它们包裹起来。
例如,你可以使用一个<div>标签:
| <div> <h1>海蒂·拉玛的待办事项</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" > <ul> ... </ul> </div> |
如果你不想在标签中增加一个额外的<div>,可以用<>和</>元素来代替:
| <> <h1>海蒂·拉玛的待办事项</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" > <ul> ... </ul> </> |
这个空标签被称作Fragment。React Fragment允许你将子元素分组,而不会在HTML结构中添加额外节点。
为什么多个JSX标签需要被一个父元素包裹?
JSX虽然看起来很像HTML,但在底层其实被转化为了JavaScript对象,你不能在一个函数中返回多个对象,除非用一个数组把他们包装起来。这就是为什么多个JSX必须要用一个父元素或者Fragment来包裹。
- 标签必须闭合
JSX要求标签必须正确闭合。像<img>这样的自闭合标签必须书写成<img />,而像<li>oranges这样只有开始标签的元素必须带有闭合标签,需要改为<li>oranges</li>。
海蒂-拉玛的照片和待办事项的标签经修改后变为:
| <> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" /> <ul> <li>发明一种新式交通信号灯</li> <li>排练一个电影场景</li> <li>改进频谱技术</li> </ul> </> |
- 使用驼峰式命名法给大部分属性命名!
JSX最终会被转化为JavaScript,而JSX中的属性也会变成JavaScript对象中的键值对。在你自己的组件中,经常会遇到需要用变量的方式读取这些属性的时候。但JavaScript对变量的命名有限制。例如,变量名称不能包含 - 符号或者像class这样的保留字。
这就是为什么在React中,大部分HTML和SVG属性都用驼峰命名法表示。例如,需要用strokeWith代替stroke-with。由于class是一个保留字,所以在React中需要用className来代替。这也是DOM属性中的命名:
| <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" className="photo" /> |
你可以在React DOM元素中找到所有对应的属性。如果你在编写属性时发生了错误,不用担心--React会在浏览器控制台中打印一条可能得更正信息。
关于组件的文档:普通组件(例如 <div>) – React 中文文档
关于Hook的文档:React 内置 Hook – React 中文文档
关于API的文档:内置的 React API – React 中文文档
陷阱:由于历史原因,aria-*和data-*属性是以带 - 符号的HTML格式书写的。
高级提示:使用JSX转化器
将现有的HTML中的所有属性转化JSX的格式是很繁琐的。我们建议使用转化器将HTML和SVG标签转化为JSX。这种转化器在实践中非常有用。但我们依然有必要去了解这种转化过程中发生了什么,这样你就可以编写自己的JSX了。
这是最终的结果:
| export default function TodoList() { return ( <> <h1>海蒂·拉玛的待办事项</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" className="photo" /> <ul> <li>发明一种新式交通信号灯</li> <li>排练一个电影场景</li> <li>改进频谱技术</li> </ul> </> ); } |
转换JSX工具如图:

转换工具链接(JSX、JSON、JAVA、TypeScript):JavaScript to Typescript
摘要
现在你知道了为什么我们需要JSX以及如何在组件中使用它:
-由于渲染逻辑和标签是紧密相关的,所以React将它们存放在一个组件中。
-JSX类似HTML,不过有一些区别。如果需要的话可以使用转化器将HTML转化为JSX。
-错误提示通常会指引你将标签修改为正确的格式。
120

被折叠的 条评论
为什么被折叠?



