JSX是React引入的一项技术。让我们深入研究
JSX简介
JSX是React引入的一项技术。
尽管React无需使用JSX即可完全正常工作,但这是处理组件的理想技术,因此React从JSX中受益匪浅。
最初,您可能会认为使用JSX就像将HTML和JavaScript(以及您将看到的CSS)。
但这是不正确的,因为使用JSX语法时,您实际上正在写有关组件UI应该是什么的声明性语法。
而且您正在描述的UI不是使用字符串,而是使用JavaScript,这使您可以做很多事情。
JSX入门
这是定义包含字符串的h1标签的方法:
const element = <h1>Hello, world!</h1>
它看起来像JavaScript和HTML的奇怪组合,但实际上,它们全都是JavaScript。
看起来像HTML的实际上是用于定义组件及其在标记内的位置的语法糖。
在JSX表达式中,可以很容易地插入属性:
const myId = 'test'
const element = <h1 id={myId}>Hello, world!</h1>
您只需要在属性带有破折号(-
),而是将其转换为camelCase语法,以及以下2种特殊情况:
class
变成className
for
变成htmlFor
因为它们是JavaScript中的保留字。
这是一个JSX代码段,将两个组件包装到一个div
标签:
<div>
<BlogPostsList />
<Sidebar />
</div>
始终需要关闭标签,因为XML比HTML多(如果您还记得XHTML的日子,这会很熟悉,但是从那时起,HTML5宽松的语法就赢了)。在这种情况下,使用自动关闭标签。
请注意,我是如何将2个组件包装到一个div
。为什么?因为render()函数只能返回一个节点,因此,如果您要返回2个同级,只需添加一个父级即可。它可以是任何标签,而不仅仅是div
。
转译JSX
浏览器无法执行包含JSX代码的JavaScript文件。必须首先将它们转换为常规JS。
如何?通过执行一个称为转堆。
我们已经说过JSX是可选的,因为对于每条JSX行,都可以使用相应的普通JavaScript替代品,这就是JSX被移植到的内容。
例如,以下两个构造是等效的:
普通JS
ReactDOM.render(
React.createElement('div', { id: 'test' },
React.createElement('h1', null, 'A title'),
React.createElement('p', null, 'A paragraph')
),
document.getElementById('myapp')
)
JSX
ReactDOM.render(
<div id="test">
<h1>A title</h1>
<p>A paragraph</p>
</div>,
document.getElementById('myapp')
)
这个非常基本的示例只是起点,但是您已经可以看到,与使用JSX相比,普通的JS语法要复杂得多。
在撰写本文时,最流行的方式是移植是用巴别塔,这是运行时的默认选项create-react-app
,因此,如果您使用它,则不必担心,一切都会在您的幕后发生。
如果你不使用create-react-app
您需要自己设置Babel。
JSX中的JS
JSX接受任何类型的JavaScript混合。
每当您需要添加一些JS时,只需将其放在花括号中{}
。例如,以下是使用在其他地方定义的常量值的方法:
const paragraph = 'A paragraph'
ReactDOM.render(
<div id="test">
<h1>A title</h1>
<p>{paragraph}</p>
</div>,
document.getElementById('myapp')
)
这是一个基本的例子。大括号接受任何JS代码:
const paragraph = 'A paragraph'
ReactDOM.render(
<table>
{rows.map((row, i) => {
return <tr>{row.text}</tr>
})}
</table>,
document.getElementById('myapp')
)
如你看到的我们将JavaScript嵌套在JSX内,将其嵌套在JSX中。您可以根据需要进行深入研究。
JSX中的HTML
JSX非常类似于HTML,但实际上是XML语法。
最后,您呈现HTML,因此您需要了解如何在HTML中定义某些内容与如何在JSX中定义它们之间的一些区别。
您需要关闭所有标签
就像在XHTML中一样,如果您曾经使用过它,则需要关闭所有标签:不再<br>
而是使用自动关闭标签:<br />
(其他标签也是如此)
camelCase是新标准
在HTML中,您会发现没有任何大小写的属性(例如,onchange
)。在JSX中,它们被重命名为其等效的camelCase:
onchange
=>onChange
onclick
=>onClick
onsubmit
=>onSubmit
class
变成className
由于JSX是JavaScript,class
是保留字,你不能写
<p class="description">
但是你需要使用
<p className="description">
同样适用于for
被翻译成htmlFor
。
样式属性更改其语义
这style
HTML中的属性允许指定内联样式。在JSX中,它不再接受字符串,而在React中的CSS您会明白为什么这是一个非常方便的更改。
形式
表单字段定义和事件在JSX中进行了更改,以提供更多的一致性和实用性。
JSX中的表单详细介绍表格。
React中的CSS
JSX提供了一种定义CSS的好方法。
如果您对HTML内联样式有一点经验,乍一看就会发现自己落后了10或15年,进入了内联CSS完全正常的世界(如今已经被妖魔化了,通常只是“快速修复”)解决方案)。
JSX样式不是一回事:首先,JSX而不是接受包含CSS属性的字符串style
属性仅接受一个对象。这意味着您在对象中定义属性:
var divStyle = {
color: 'white'
}
ReactDOM.render(<div style={divStyle}>Hello World!</div>, mountNode)
或者
ReactDOM.render(<div style={{ color: 'white' }}>Hello World!</div>, mountNode)
您在JSX中编写的CSS值与普通CSS略有不同:
- 键属性名称为camelCased
- 值只是字符串
- 您用逗号分隔每个元组
为什么相对于普通CSS / SASS / LESS,这是首选?
CSS是一个未解决的问题。自成立以来,围绕它的数十种工具先涨后跌。 CSS的主要问题是没有作用域,并且很容易编写不以任何方式强制执行的CSS,因此“快速修复”会影响不应被触及的元素。
JSX允许组件(例如在React中定义)完全封装其样式。
这是首选解决方案吗?
除非需要,否则JSX中的内联样式会很好。
- 撰写媒体查询
- 样式动画
- 参考伪类(例如
:hover
) - 参考伪元素(例如
::first-letter
)
简而言之,它们涵盖了基础知识,但这不是最终的解决方案。
JSX中的表单
JSX对HTML表单的工作方式进行了一些更改,目的是使开发人员更轻松。
value
和defaultValue
这value
属性始终保存该字段的当前值。
这defaultValue
属性包含创建字段时设置的默认值。
这有助于解决常规的一些怪异行为DOM检查时的互动input.value
和input.getAttribute('value')
返回一个当前值和一个原始默认值。
这也适用于textarea
领域,例如
<textarea>Some text</textarea>
但反而
<textarea defaultValue={'Some text'} />
为了select
字段,而不是使用
<select>
<option value="x" selected>
...
</option>
</select>
使用
<select defaultValue="x">
<option value="x">...</option>
</select>
更一致的onChange
将功能传递给onChange
属性,您可以订阅表单字段上的事件。
即使在各个领域,它也能一致地工作radio
,select
和checkbox
输入字段触发onChange
事件。
onChange
在输入字符时也会触发input
或者textarea
场地。
JSX自动转义
为了减轻XSS漏洞的风险,JSX强制表达式自动转义。
这意味着在字符串表达式中使用HTML实体时,您可能会遇到问题。
您希望以下内容能够打印© 2020
:
<p>{'© 2020'}</p>
但这不是,它是印刷品© 2020
因为该字符串已转义。
要解决此问题,您可以将实体移到表达式外:
<p>© 2020</p>
或者使用一个常量来打印与您需要打印的HTML实体相对应的Unicode表示形式:
<p>{'\u00A9 2020'}</p>
JSX中的空白
要在JSX中添加空格,有2条规则:
Horizontal white space is trimmed to 1
如果同一行中的元素之间有空格,则所有空格都将修剪为1个空格。
<p>Something becomes this</p>
变成
<p>Something becomes this</p>
消除了垂直空白
<p>
Something
becomes
this
</p>
变成
<p>Somethingbecomesthis</p>
要解决此问题,您需要通过添加如下所示的空格表达式来显式添加空格:
<p>
Something
{' '}becomes
{' '}this
</p>
或通过将字符串嵌入空格表达式中:
<p>
Something
{' becomes '}
this
</p>
在JSX中添加评论
您可以使用表达式中的普通JavaScript注释向JSX添加注释:
<p>
{/* a comment */}
{
//another comment
}
</p>
传播属性
在JSX中,常见的操作是为属性分配值。
而不是手动进行操作,例如
<div>
<BlogPost title={data.title} date={data.date} />
</div>
你可以通过
<div>
<BlogPost {...data} />
</div>
以及data
借助ES6,该对象将自动用作属性点差算子。
如何在JSX中循环
如果您需要循环生成一组JSX局部元素,则可以创建一个循环,然后将JSX添加到数组中:
const elements = [] //..some array
const items = []
for (const [index, value] of elements.entries()) {
items.push(<Element key={index} />)
}
现在,当渲染JSX时,您可以嵌入items
通过将其包装在花括号中来排列数组:
const elements = ['one', 'two', 'three'];
const items = []
for (const [index, value] of elements.entries()) {
items.push(<li key={index}>{value}</li>)
}
return (
<div>
{items}
</div>
)
您可以直接在JSX中执行以下操作:map
而不是for-of循环:
const elements = ['one', 'two', 'three'];
return (
<ul>
{elements.map((value, index) => {
return <li key={index}>{value}</li>
})}
</ul>
)
免费下载我的反应手册
更多反应教程:
- 一个React简单的应用示例:通过API获取GitHub用户信息
- 用React构建一个简单的计数器
- 用于React开发的VS代码设置
- 如何通过React Router将道具传递给子组件
- 使用Electron和React创建一个应用
- 教程:使用React创建电子表格
- 学习React的路线图
- 了解如何使用Redux
- JSX入门
- 样式化的组件
- Redux Saga简介
- React Router简介
- React简介
- 反应组件
- 虚拟DOM
- 反应事件
- 反应状态
- 反应道具
- 反应片段
- React Context API
- 反应PropTypes
- 反应概念:声明式
- React:如何在点击时显示其他组件
- 如何在React JSX内部循环
- 道具与状态在React中
- 您应该使用jQuery还是React?
- 使用React需要知道多少JavaScript?
- 盖茨比介绍
- 如何在React中引用DOM元素
- React中的单向数据流
- 反应高阶组件
- 反应生命周期事件
- 反应概念:不变性
- 反应概念:纯度
- React钩子简介
- create-react-app简介
- 反应概念:组成
- React:演示组件与容器组件
- React中的代码拆分
- 使用React进行服务器端渲染
- 如何安装React
- React中的CSS
- 在React中使用SASS
- 在React中处理表单
- 反应严格模式
- 反应门户
- 反应渲染道具
- 测试React组件
- 如何在React中将参数传递给事件处理程序
- 如何处理React中的错误
- 如何在JSX中返回多个元素
- React中的条件渲染
- 反应,如何将道具转移到子组件
- 如何在React中获取输入元素的值
- 如何使用useState React钩子
- 如何使用useCallback React钩子
- 如何使用useEffect React钩子
- 如何使用useMemo React钩子
- 如何使用useRef React钩子
- 如何使用useContext React钩子
- 如何使用useReducer React钩子
- 如何将您的React应用程序连接到相同来源的后端
- 到达路由器教程
- 如何使用React Developer Tools
- 如何学习React
- 如何调试React应用程序
- 如何在React中呈现HTML
- 如何修复`dangerouslySetInnerHTML`与React中的错误不匹配
- 我如何解决React登录表单状态和浏览器自动填充的问题
- 如何在本地主机上的React应用程序中配置HTTPS
- 如何修复React中的“渲染其他组件时无法更新组件”错误
- 我可以在条件内使用React挂钩吗?
- 将useState与对象一起使用:如何更新
- 如何使用React和Tailwind在代码块中移动
- React,添加到DOM时将焦点放在React中的一个项目上
- 反应,在doubleclick上编辑文本