React 基础 JSX 语法
const element = <h1>Hello, world!</h1>;
上面这个 JSX 标签语法既不是 字符串 也不是 HTML ,是一个 JavaScript 的语法扩展。
Babel 会把 JSX 转译成一个名为 React.createElement()
函数调用。
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
// 上面的代码完全等效于下面代码
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
React.createElement()
会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:
// 注意:这是简化过的结构
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
这些对象被称为 “React 元素”。它们描述了你希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 以及保持随时更新。
JSX 中 嵌入表达式
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
你可以在大括号内放置任何有效的 JavaScript 表达式 。例如, 2 + 2
, user.firstName
或 formatName(user)
都是有效的 JavaScript 表达式
JSX 中 指定属性
const element = <a href="https://www.reactjs.org"> link </a>;
const element = <img src={user.avatarUrl}></img>;
因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase
(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。
例如,JSX 里的 class
变为 className
, tabindex
变为 tabIndex
。
JSX 防止注入攻击
const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;
你可以安全地在 JSX 当中 插入用户输入内容 ,这是因为 React DOM
在渲染所有输入内容之前,默认会进行 转义 。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本) 攻击。
一、在运行时选择类型
你不能将通用表达式作为 React 元素类型。如果你想通过通用表达式来(动态)决定元素类型,你需要首先将它赋值给大写字母开头的变量。这通常用于根据 prop 来渲染不同组件的情况下:
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// 错误!JSX 类型不能是一个表达式。
return <components[props.storyType] story={props.story} />;
}
要解决这个问题, 需要首先将类型赋值给一个大写字母开头的变量:
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// 正确!JSX 类型可以是大写字母开头的变量。
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
二、函数作为子元素
通常,JSX 中的 JavaScript 表达式将会被计算为字符串、React 元素或者是列表。不过, props.children
和其他 prop 一样,它可以传递任意类型的数据,而不仅仅是 React 已知的可渲染类型。例如,如果你有一个自定义组件,你可以把回调函数作为 props.children
进行传递:
// 调用子元素回调 numTimes 次,来重复生成组件
function Repeat(props) {
let items = [];
for (let i = 0; i < props.numTimes; i++) {
items.push(props.children(i));
}
return <div>{items}</div>;
}
function ListOfTenThings() {
return (
<Repeat numTimes={10}>
{(index) => <div key={index}>This is item {index} in the list</div>}
</Repeat>
);
}
你可以将任何东西作为子元素传递给自定义组件,只要确保在该组件渲染之前能够被转换成 React 理解的对象。这种用法并不常见,但可以用于扩展 JSX。
三、布尔类型、Null 以及 Undefined 将会忽略
false
, true
, null
, undefined
是合法的子元素。但它们并不会被渲染。以下的 JSX 表达式渲染结果相同:
<div />
<div></div>
<div>{false}</div>
<div>{null}</div>
<div>{undefined}</div>
<div>{true}</div>
这有助于依据特定条件来渲染其他的 React 元素。例如,在以下 JSX 中,仅当 showHeader
为 true
时,才会渲染 <Header />
组件:
<div>
{showHeader && <Header />}
<Content />
</div>
值得注意的是有一些 “falsy” 值 ,如数字 0
,仍然会被 React 渲染。例如,以下代码并不会像你预期那样工作,因为当 props.messages
是空数组时,将会渲染为数字 0
:
<div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>
要解决这个问题,确保 &&
之前的表达式总是布尔值:
<div>
{props.messages.length > 0 &&
<MessageList messages={props.messages} />
}
</div>
反之,如果你想渲染 false
、 true
、 null
、 undefined
等值,你需要先将它们 转换为字符串 :
<div>
My JavaScript variable is {String(myVariable)}.
</div>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: React 高阶组件
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论