React(2-1):JSX入门
JSX 基础
介绍
1 | const element = <p>Hello, world!</p>; |
这种看上去像 html 的东西便是 jsx。
一段 jsx 代码必须有一个根元素,也就是说,下面的代码是错的:
1 | const element = <p>Hello, world!</p><p>Hello, world!</p>; |
在项目中使用 jsx
前面提到,jsx 最终会编译成 React.createElement。
因此,在使用 jsx 语法之前,应该引入 React,尽管它可能没有在其他的地方被使用:
1 | import React from 'react'; // 引入 React 才能使用 jsx |
多行jsx
如果你的 jsx 比较长,可以将它拆分成多行,不过需要加上一对括号:
1 | const el = ( |
插入 js 表达式
可以使用 {} 来嵌入表达式:
1 | const name = 'kaz'; |
绑定子元素
这和 html 是一样的。
1 |
|
除了这样写,还可以往元素的内容里传入另一个 React DOM 对象:
1 | const title = <h1>标题</h1>; |
这时这个这个 React DOM 将作为 el 的子元素。
闭合标签
如果标签内没有内容,那么可以使用 /结尾
1 | const el = <img src="https://api.r10086.com/%E9%A3%8E%E6%99%AF%E7%B3%BB%E5%88%976.php" />; |
不渲染的子元素
false, null, undefined, 以及 true 是合法的子元素。但它们并不会被渲染:[1]
1 | const el = <div>{null}</div>; //渲染出的 div 里面不会有任何东西 |
如果你想把这些内容输出到 UI 上,那么你得手动转换成字符串。
1 | const el = <div>{String(null)}</div>; |
绑定属性
介绍
如果只是一个普通字符串,那么这和 html 是一样
1 | const el = <font color="red">hello world!</font>; |
也可以通过大括号来传入 js 表达式:
1 | const color = 'red'; |
批量绑定属性
除了这种绑定方式,我们还可以通过剩余运算符来批量绑定:
1 | const props = {color: 'red', size: 18}; |
在批量绑定属性后,可以继续绑定属性,遇到相同的属性则会覆盖:
1 | const props = {color: 'red', size: 18}; |
但在批量绑定之前的属性则不会起作用:
1 | const props = {color: 'red', size: 18}; |
使用原始 html 字符串
这是十分危险的行为,应该尽量避免
可以通过 dangerouslySetInnerHTML 属性传入一个原始的 html 字符串。当你想设置 dangerouslySetInnerHTML 时,需要向其传递包含 key 为 __html 的对象。
绑定事件
介绍
jsx 中的事件和 html 有一些不同:
- React 事件的命名采用小驼峰式,而不是小写。例如
onClick - 使用 JSX 语法时你需要传入一个函数作为事件处理函数
1 |
|
小心 this 指向
注意一点,事件处理函数是直接调用的,如果你使用了 this,这可能是一个雷:
1 |
|
这时候你点击按钮,发现控制台输出的是 undefined。
这是因为,事件处理函数最终是通过 func() 这样调用的,它并没有挂载到某一个对象上。最终,它的指向会是 globalThis。
为了避免这个问题,你应该使用 箭头函数,或者使用 bind 函数绑定 this 的指向。
1 | let handleClick = () => { |
在类组件中,这种问题是很容易出现的。
一般的做法是,会在组件的构造函数中手动绑定 this:
1 | this.handleClick = this.handleClick.bind(this); |
获取事件发生的对象
通常使用 e.target 来获取触发事件对象。但这有可能是绑定事件的内部元素。
1 | <div onclick="console.log(event.target, event.currentTarget)"> |
我们运行这个例子,当按钮点击的时候,event.target 便是按钮,而 event.currentTarget 则是绑定事件的元素。
这说明:
e.target得到的是触发事件的DOM, 但触发事件的DOM可能是子元素。e.currentTarget得到是触发事件时,事件绑定的DOM。
绑定样式
绑定 class
由于 class 是关键字,所以不能使用 class 来绑定样式,而使用 className 属性来绑定样式:
1 | const el = <div className="active"></div>; |
如果你用过 Vue 并且希望能够使用其中的数组语法、对象语法,classnames 这个包或许是不错的选择。
绑定 style
对于 style,只需要传递一个小驼峰对象即可:
1 | const el = <div style={{color:'red', fontSize: 14, borderRadius: '50%'}}>一些内容</div>; |
需要注意的是:
- 对于大小,
React会自动补上px单位 - 不会针对旧浏览器提供兼容性前缀。浏览器引擎前缀都应以大写字母开头,除了 ms。因此,WebkitTransition 首字母为 ”W”。
使用CSS模块
在前面一个搭建好的 React项目中,我们可以康康 App.js:
1 | import logo from './logo.svg'; |
这里的第二行挺有趣的,直接 import 了一个 App.css。
实际上,我们创建的 React 项目,在浏览器运行前会经历一个构建的过程,在这个过程中,会对各种类型的代码进行打包。
当我们使用 import 引入了一个 CSS 文件时,构建工具会自动将 CSS 文件加载到网页的 <style> 标签中。
至于这些操作具体是怎么完成的,将会在后面的 Webpack 相关文章中解释
但这也有一些缺点,这些类名都是全局的,一旦出现了什么相同的 class,很容易出现全局命名污染。
于是便有了CSS 模块。
要在一个 React 项目中使用 CSS 模块,需要保证 css 文件的后缀是 .module.css,否则它将会被当做全局 CSS 文件,而不是作为 CSS 模块。
我们先建立一个简单的 css 文件:
1 | .panel { |
然后在 App.js引入这个文件:
1 | import logo from './logo.svg'; |
注意 CSS 模块的引入和前面的引入方法有些不一样。
然后在下面的 App 函数中加入这些:
1 | </header> |
接下来打开界面,我们就可以看到效果:

打开浏览器控制台,我们可以看到页面增加的 CSS 样式:

可以看到,构建工具会自动将 CSS 模块编译成带随机前后缀的全局 CSS 样式,进而确保样式在全局是唯一的。
我们再看看我们引入的 class,刚好是编译后的 class。

当一个 css 模块被引入时,它会被解析成一个 javascript 对象,其键是原来的属性名,其值是编译后的属性名。
如果一个 css 样式比较复杂,则属性名为最后一级的 css 选择器。
例如上面的 .post .title,对应的键就是 title。
关于 CSS 模块更详细的说明,可以参考:
引入媒体资源
在浏览器中引入图片、视频等媒体资源是比较简单的。这里只说明在 React 项目中引入媒体资源的方法。
使用 import
要想在项目中引入一个媒体资源,只需要将资源 import 进来即可。
比若说我们的 App.js:
1 | import logo from './logo.svg'; |
第一行就引用了图片资源,然后在后面使用了它:
1 | <img src={logo} className="App-logo" alt="logo" /> |
但这似乎是多次一举,因为这种链接我可以直接写死在属性里:
1 | <img src="./logo.svg" className="App-logo" alt="logo" /> |
但这样操作后,图片就打不开了:

这是因为,项目在构建的时候,图片、视频、脚本等等资源的位置会发生变化,它和 src 中的目录是不一样的。
例如,图片会最终放到 /images 目录下。但开发状态下,我们可能就直接放到 src 目录了。
此外,构建工具为了考虑性能,减小网络请求,通常会把非常小的图片直接使用 base64 编码,然后内嵌到网页中。这种情况下,images 目录就看不到相应的图片了。
不使用 import
如果不想通过 import 的方式来引入媒体资源,我们可以把它们移动到 public 目录下。
构建时,public 目录下的文件会被直接复制到项目打包后的文件夹下,路径啥的都不会变化。
在搭好的项目中, public 目录刚好有一个 logo512.png,我们可以修改 App.js 文件:
1 | <img src="./logo512.png" className="App-logo" alt="logo" /> |
然后,图片就正常显示了。
- 标题: React(2-1):JSX入门
- 作者: ObjectKaz
- 创建于: 2021-05-03 05:56:03
- 更新于: 2023-05-25 17:10:50
- 链接: https://www.objectkaz.cn/33d37bb27182.html
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。