React17 高级指引 深入JSX
实际上,JSX 仅仅只是 React.createElement(component, props, ...children)
函数的语法糖。
1 | // 编译前 |
指定 React 元素类型
JSX 标签的第一部分指定了 React 元素的类型。
大写字母开头的 JSX 标签意味着它们是 React 组件。这些标签会被编译为对命名变量的直接引用。
React 必须在作用域内
由于 JSX 会编译为 React.createElement
调用形式,所以 React
库也必须包含在 JSX 代码作用域内。
例如,在如下代码中,虽然 React
和 CustomButton
并没有被直接使用,但还是需要导入:
1 | import React from 'react';import CustomButton from './CustomButton'; |
如果你不使用 JavaScript 打包工具而是直接通过 <script>
标签加载 React,则必须将 React
挂载到全局变量中。
在 JSX 类型中使用点语法
在 JSX 中,你也可以使用点语法来引用一个 React 组件。
当你在一个模块中导出许多 React 组件时,这会非常方便。
1 | import React from 'react'; |
用户定义的组件必须以大写字母开头
1 | import React from 'react'; |
在运行时选择类型
你不能将通用表达式作为 React 元素类型。如果你想通过通用表达式来(动态)决定元素类型,你需要首先将它赋值给大写字母开头的变量。
这通常用于根据 prop 来渲染不同组件的情况下:
1 | import React from 'react'; |
JSX 中的 Props
有多种方式可以在 JSX 中指定 props。
JavaScript 表达式作为 Props
你可以把包裹在 {}
中的 JavaScript 表达式作为一个 prop 传递给 JSX 元素。
1 | <MyComponent foo={1 + 2 + 3 + 4} /> |
字符串字面量
如下两个 JSX 表达式是等价的:
1 | <MyComponent message="hello world" /> |
1 | <MyComponent message="<3" /> |
Props 默认值为 “True”
以下两个 JSX 表达式是等价的:
1 | <MyTextBox autocomplete /> |
属性展开
如果你已经有了一个 props 对象,你可以使用展开运算符 ...
来在 JSX 中传递整个 props 对象。
以下两个组件是等价的:
1 | function App() { |
JSX 中的子元素
包含在开始和结束标签之间的 JSX 表达式内容将作为特定属性 props.children
传递给外层组件。
有几种不同的方法来传递子元素:
字符串字面量
你可以将字符串放在开始和结束标签之间,此时 props.children
就只是该字符串。
1 | <MyComponent>Hello world!</MyComponent> |
JSX 会移除行首尾的空格以及空行。与标签相邻的空行均会被删除,文本字符串之间的新行会被压缩为一个空格。
因此以下的几种方式都是等价的:
1 | <div>Hello World</div> |
JSX 子元素
子元素允许由多个 JSX 元素组成。这对于嵌套组件非常有用:
1 | <MyContainer> |
React 组件也能够返回存储在数组中的一组元素:
1 | render() { |
JavaScript 表达式作为子元素
JavaScript 表达式可以被包裹在 {}
中作为子元素。例如,以下表达式是等价的:
1 | <MyComponent>foo</MyComponent> |
这对于展示任意长度的列表非常有用。例如,渲染 HTML 列表:
1 | function Item(props) { |
JavaScript 表达式也可以和其他类型的子元素组合。这种做法可以方便地替代模板字符串:
1 | function Hello(props) { |
函数作为子元素
通常,JSX 中的 JavaScript 表达式将会被计算为字符串、React 元素或者是列表。不过,props.children
和其他 prop 一样,它可以传递任意类型的数据,而不仅仅是 React 已知的可渲染类型。
1 | // 调用子元素回调 numTimes 次,来重复生成组件 |
布尔类型、Null 以及 Undefined 将会忽略
false
, null
, undefined
, and true
是合法的子元素。但它们并不会被渲染。以下的 JSX 表达式渲染结果相同:
1 | <div /> |
值得注意的是有一些 “falsy” 值,如数字 0
,仍然会被 React 渲染。例如,以下代码并不会像你预期那样工作,因为当 props.messages
是空数组时,0
仍然会被渲染:
1 | <div> |
要解决这个问题,确保 &&
之前的表达式总是布尔值:
1 | <div> |
反之,如果你想渲染 false
、true
、null
、undefined
等值,你需要先将它们转换为字符串:
1 | <div> |