深入JSX

深入JSX

HTML标签和React组件

React既可以渲染HTML标签,也可以渲染React组件。
在JSX语法中,html标签一般以小写字母打头,如:

var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));

在React组件中,一般是先定义一个以大写字打头的本地变量,使用时在<>中写上变量名即可,如下

var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.getElementById('example'));

注: jsx也属于javascript,class和for两个属性为javascript的关键字,在定义 React组件时,应将其分别写成className和htmlFor。

将React jsx转化成javascript

JSX语法写成的语句,都会被转化成原生的javascript里的xml元素,其属性和子节点将作为参数传递给React.createElement方法。如

var Nav;
// Input (JSX):
var app = <Nav color="blue" />;
// Output (JS):
var app = React.createElement(Nav, {color:"blue"});

定义 了一个名字为Nav的React组件。通过jsx可以直接写成:var app = < Nav color=”blue” />; 与纯javascript写的:var app = React.createElement(Nav, {color:”blue”}); 意思是一样的。

JSX也允许指定子节点,如

var Nav, Profile;
// Input (JSX):
var app = <Nav color="blue"><Profile>click</Profile></Nav>;
// Output (JS):
var app = React.createElement(
  Nav,
  {color:"blue"},
  React.createElement(Profile, null, "click")
);

当组件的displayName属性没有定义时,其默认值为变量名,如

// Input (JSX):
var Nav = React.createClass({ });
// Output (JS):
var Nav = React.createClass({displayName: "Nav", });

Namespaced 组件

如果定义一个组件有许多个子组件,比如form,必须得声明多个变量,如

// Awkward block of variable declarations
var Form = MyFormComponent;
var FormRow = Form.Row;
var FormLabel = Form.Label;
var FormInput = Form.Input;

var App = (
  <Form>
    <FormRow>
      <FormLabel />
      <FormInput />
    </FormRow>
  </Form>
);

这样看起来很麻烦,为了简单和方便,可以使用namespaced 组件。定义时可将子组件定义为父组件的属性,如下

var MyFormComponent = React.createClass({ ... });

MyFormComponent.Row = React.createClass({ ... });
MyFormComponent.Label = React.createClass({ ... });
MyFormComponent.Input = React.createClass({ ... });

使用时,可通过如下方式

var Form = MyFormComponent;

var App = (
  <Form>
    <Form.Row>
      <Form.Label />
      <Form.Input />
    </Form.Row>
  </Form>
);

JSX能正确编译代码:

var App = (
  React.createElement(Form, null,
    React.createElement(Form.Row, null,
      React.createElement(Form.Label, null),
      React.createElement(Form.Input, null)
    )
  )
);

该功能只在V0.11及以上版本提供。

javascript表达式

表达式 属性

JSX语法中,使用javascript表达式作为属性值 时,必须将表达式以{}括起来,而不能直接用”“

// Input (JSX):
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
// Output (JS):
var person = React.createElement(
  Person,
  {name: window.isLoggedIn ? window.name : ''}
);

boolean属性

JSX 中,如果不写某个属性的值,那么其值默认为true。 即如果想要某个属性值 为true,要么不赋给它值 ,要么使用{true},如果想要某个属性值 为false,要么不写该属性,要么将其值设置为{false},比如给html里的form标签设置disabled, required,checked,readonly属性时:

// These two are equivalent in JSX for disabling a button
<input type="button" disabled />;
<input type="button" disabled={true} />;

// And these two are equivalent in JSX for not disabling a button
<input type="button" />;
<input type="button" disabled={false} />

子节点

也可以通过javascript表达式增加子节点,如

// Input (JSX):
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// Output (JS):
var content = React.createElement(
  Container,
  null,
  window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
);

添加注释

// 注释一行
/* */注释一段代码。
但需要特别注意的是:如果在标签子节点前添加注释时,需要将注释以{}包围。如

var content = (
  <Nav>
    {/* child comment, put {} around */}
    <Person
      /* multi
         line
         comment */
      name={window.isLoggedIn ? window.name : ''} // end of line comment
    />
  </Nav>
);

JSX传播属性

如果事先知道组件的所有属性值,可以如下使用JSX:

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

最好不要先声明组件,再声明其属性值,类似如下的声明最好不要用:

var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad

可通过如下方式声明:

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

对象props的属性值是复制给Component的属性的,因此是不可变的。**注意使用…操作符(ES6数组中也支持…操作符)**props可以多次使用,也可以与其他属性一起使用。 属性赋值的顺序很重要,后赋值的属性会覆盖之前赋值的属性。

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

JSX进阶

JSX看起来像html但与html有些许不同。

HTML特殊字符

可以直接在JSX中插入HTML特殊字符:

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

React会转义所有的字符串来防止XSS攻击,因此如果需要动态展示HTML特殊字符,在{}中写入转义字符,最后可能并不能正确显示,如

// Bad: It displays "First &middot; Second"
<div>{'First &middot; Second'}</div>

如果需要在{}中展示html特殊字符有如下几种办法:
- 最简单的方法,直接在javascript中写入特殊字符,不使用转义,但是必须确保文件以UTF-8格式保存,并且浏览器能正确显示

<div>{'First · Second'}</div>
  • 最安全的做法,直接在javascript中写入其unicode,如下:
<div>{'First \u00b7 Second'}</div>
<div>{'First ' + String.fromCharCode(183) + ' Second'}</div>
  • 也可以使用数组的方式,如下
<div>{['First ', <span>&middot;</span>, ' Second']}</div>
  • 也可以直接插入原始的HTML,如下:不推荐。
<div dangerouslySetInnerHTML={{__html: 'First &middot; Second'}} />

定制的HTML属性

如果向HTML元素中传入一些自定义的属性,React并不会对其进行渲染。如果需要使用自定义属性,最好加上data-前缀

<div data-custom-attribute="foo" />

如果是在自定义元素上使用自定义属性也是支持的,属性前面不需要加data-前缀。

<x-my-component custom-attribute="foo" />

web相关的属性即以aria-前缀的属性能够被react正确渲染,如:

<div aria-hidden={true} />

链接:https://www.zybuluo.com/ttingtu/note/249363
参考资料:
- http://facebook.github.io/react/docs/jsx-in-depth.html
- http://facebook.github.io/react/docs/jsx-spread.html
- http://facebook.github.io/react/docs/jsx-gotchas.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值