请看下面的一个定义:

const element = <h1>Hello, world!</h1>;

它既不是一个 string 也不是 html。它叫做 JSX,是一种对 JavaScript 语法的扩展。推荐在 React 中使用 JSX 来描述 UI,它用来创建 React 类型的 elements 然后将其在 DOM 中渲染。

下面对 JSX 做一些基本介绍。

使用 JSX 的原因

React 认同这种观点:渲染逻辑结构和 UI 逻辑结构是原生相互耦合的,events 的处理,状态的变化,数据何时显示等。不同于人为的将 markup 部分和 logic 逻辑部分放在单独的文件,React 的耦合单元叫做 components 可以同时包含 markup 和 logic 部分。

React 并不强制要求使用 JSX,但是大部分开发者认为它可以帮助在 JavaScript 中处理 UI 的问题。它也可以帮助 React 显示更多的 error 或 warning 信息。

JSX 中使用 JavaScript 表达式

下面的示例中,我们声明一个变量并在 JSX 中通过大括号{} 调用变量:

const name = 'marco nie';
const element = <h1>hello, {name}</h1>

ReactDOM.render(
    element,
    document.getElementById('root')
);

我们可以将任意的 JavaScript 表达式通过大括号{}放如 JSX 中。例如:1 + 1user.name 都是有效的 JavaScript 表达式:

const city = 'han zhong';
const user = {
    name: 'marco',
    age: 20
}
const element = <h1>hello, {user.name}, from {city}, time: {1 + 20}</h1>

可以将 JSX 分割成多行以提高代码可读性,需要使用小括号包围起来,防止编译器错误的自动添加分行符:

const element = (
    <h1>
        hello, {user.name}, from {city}, time: {1 + 20}
    </h1>
);

编译后 JSX 表达式会转换为通用的 JavaScript function 或 objects。这就意味着我们可以在 if 或 for 表达式中,传入数据中或者 返回值中使用 JSX:

const testFuc = () => {
    return <h1>hello, {user.name}</h1>
}

JSX 中定义属性

可以使用引号 "" 将一个字符串作为属性:

const el1 = <div tabIndex="0"></div>

可以以通过大括号{} 将一个 JavaScript 表达式嵌入属性:

const el2 = <img src={user.name}></img>

当使用 JavaScript 嵌入属性时不能在大括号中使用引号,同一个属性中只能使用引号嵌入字符串或者大括号嵌入 JavaScript 表达式中的一种。

由于 JSX 更加接近于 JavaScript 而不是 html,所以 React 中的 DOM 使用 camelCase 属性命名规范代替 html 中的属性名称,例如 html 元素的 class 属性在 JSX 中定义为 className,tabindex 在 JSX 中为 tabIndex。

定义子元素

如果一个 tag 元素内容是空的则可以使用 /> 立刻结束定义:

const el3 = <img src=''/>

JSX tag 标签内也可以有子元素:

const el4 = (
    <div>
        <h1>hello,</h1>
        <h2>i am your friend</h2>
    </div>
);

注意只能在一个元素内定义子元素,不能直接定义两个同级的元素否则会报错。

防止 injection 注入攻击

在 JSX 中嵌入用户输入是安全的:

const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;

默认情况下 React 在渲染前会将脱开所有嵌入 JSX 中的数据,因此可以确保不会注入任何没有明确定义在应用中的数据。渲染前所有的所有内容都会转换为 string 字符串形式。则能够防止 XSS (cross-site-scripting) 攻击。

JSX 表达 objects

Babel 会将 JSX 向下编译为对 React.createElement() 的调用,以下两种定义方法是相同的:

const el5 = (
    <h1 className='test'>
        hello world
    </h1>
);
const el6 = React.createElement(
    'h1',
    {className: 'test'},
    'hello world'
)

通过 React.createElement() 创建元素会额外做一些语法检查来防止错误代码。但通常我们使用下面语法创建一个 object:

const el7 = {
    type: 'h1',
    props: {
        className: 'test',
        children: 'hello world'
    }
}

以上方式创建的 object 叫做 React elements。React 使用这些 objects 来构建 DOM 并及时更新。

推荐代码编辑器使用 Babel 语法定义环境,这样可以同时支持 ES6 和 JSX 语法结构。设置方法参考:https://babeljs.io/docs/en/editors

标签: none

添加新评论