[关闭]
@brizer 2016-01-30T11:59:29.000000Z 字数 2403 阅读 1316

JSX语法


前言

前面我们一步一步编写了一个入门级的React组件。其中用到了JSX,本文主要学习JSX的语法。


JSX就是javascript和XML结合的一种格式。我们使用React时可以不使用JSX,但是用JSX的话更加方便。

渲染html标签和react组件

React可以渲染HTML或React组件。
如果要渲染HTML标签,只需要在JSX里使用小写字母开头的标签名。

  1. var myDivElement = <div className="foo" />;
  2. React.render(myDivElement, document.body);

如果要渲染React组件,只需要创建一个大写字母开头的本地变量。

  1. var MyComponent = React.createClass({/*...*/});
  2. var myElement = <MyComponent someProperty={true} />;
  3. React.render(myElement, document.body);

也就是说,React的JSX里约定分别使用首字母大、小写来区分本地组件的类和HTML标签


转换

JSX把类XML的语法转换成javascript,XML元素、属性和子节点被转换成React.createElement的参数:

  1. var Nav;
  2. // 输入 (JSX):
  3. var app = <Nav color="blue" />;
  4. // 输出 (JS):
  5. var app = React.createElement(Nav, {color:"blue"});

注意如果要使用<Nav />,Nav变量一定要在作用区间内。

JSX也支持使用XML语法定义子节点:

  1. var Nav, Profile;
  2. // 输入 (JSX):
  3. var app = <Nav color="blue"><Profile>click</Profile></Nav>;
  4. // 输出 (JS):
  5. var app = React.createElement(
  6. Nav,
  7. {color:"blue"},
  8. React.createElement(Profile, null, "click")
  9. );

javascript表达式

属性表达式

如果需要设置属性为一个表达式,只需要用一对{}包括:

  1. // 输入 (JSX):
  2. var person = <Person name={window.isLoggedIn ? window.name : ''} />;
  3. // 输出 (JS):
  4. var person = React.createElement(
  5. Person,
  6. {name: window.isLoggedIn ? window.name : ''}
  7. );

子节点表达式

同样的,子节点也可以通过表达式来表示:

  1. // 输入 (JSX):
  2. var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
  3. // 输出 (JS):
  4. var content = React.createElement(
  5. Container,
  6. null,
  7. window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
  8. );

注释

注释需要用{}包括

  1. var content = (
  2. <Nav>
  3. {/* 一般注释, 用 {} 包围 */}
  4. <Person
  5. /* 多
  6. 注释 */
  7. name={window.isLoggedIn ? window.name : ''} // 行尾注释
  8. />
  9. </Nav>
  10. );

属性

如果事先知道组件所有属性,可以如下书写JSX:

  1. var component = <Component foo={x} bar={y} />;

如果不知道要设置哪些props,最好不要先设置它:

  1. var component = <Component />;
  2. component.props.foo = x; // 不好
  3. component.props.bar = y; // 同样不好

props应该被当做禁止修改的,因为可能导致预料之外的结果。


延展属性

为了解决上面说的那种情况,我们可以利用JSX的延展属性:

  1. var props = {};
  2. props.foo = x;
  3. props.bar = y;
  4. var component = <Component {...props} />;

传入对象的属性会被复制到组件内,它可以和其他属性一起用,但是需要注意后者会覆盖前者:

  1. var props = { foo: 'default' };
  2. var component = <Component {...props} foo={'override'} />;
  3. console.log(component.props.foo); // 'override'

JSX与HTML

JSX和HTML非常相似,但是有一些不同,比如说对于HTML实体,由于React会默认转义所有字符串来防止XSS攻击,所以下面代码:

  1. <div>First &middot; Second</div>

结果可能为:

  1. // 错误: 会显示 “First &middot; Second”
  2. <div>{'First &middot; Second'}</div>

我们有几种方式可以绕过这个限制
一,直接使用Unicode字符,例如以下:

  1. <div>{'First · Second'}</div>

需要写成如下样子:

  1. <div>{'First \u00b7 Second'}</div>
  2. <div>{'First ' + String.fromCharCode(183) + ' Second'}</div>

二,也可以在数组里混合使用字符串和JSX元素:

  1. <div>{['First ', <span>&middot;</span>, ' Second']}</div>

三,直接使用原始HTML:

  1. <div dangerouslySetInnerHTML={{__html: 'First &middot; Second'}} />

最后需要注意一点就是往原生HTML元素里传入HTML规范里不存在的属性需要使用data-前缀。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注