JSX

我们知道React使用一颗DOM对象树来描述文档,如果它是普通的对象,会是怎样?

var element = {
  tagName: 'div',
  props: {
    id: 'div',
    className: 'container'
  },
  children: [
    {
      tagName: 'div',
      props: {
        id: 'div1',
        className: 'header'
      },
      children: [...{element}]
    },
    {
      tagName: 'div',
      props: {
        id: 'div2',
        className: 'content'
      },
      children: [...{element}]
    },
    {
      tagName: 'div',
      props: {
        id: 'div3',
        className: 'footer'
      },
      children: [...{element}]
    }
  ]
}

对应的HTML

<div class="container">
  <div class="header"></div>
  <div class="content"></div>
  <div class="footer"></div>
</div>

JSX给予的方式正好相反,通过书写这样类似HTML结构,通过transformer工具将其转换成了对象,且让我们看一个不借助JSX的写法实现上面的结构。

React.createElement(
  'div',
  { className: 'container'},
  React.createElement(
    'div',
    { className: 'header'}
  ),
  React.createElement(
    'div',
    { className: 'content'}
  ),
  React.createElement(
    'div',
    { className: 'footer'}
  )
);

开始使用JSX

在今后的编程实践中期望大家使用JSX来书写React组件

利用JSX我们现在可以像写HTML一样来书写React组件,某些情况下在属性中你还需要注意JavaScript的保留字,比如class属性要写成className,for需要写成htmlFor。JSX对于大小写是敏感的,小写属于HTML标签,大写则是React组件。

使用JSX书写一个简单的组件:

import React from 'react';
import { render } from 'react-dom';

function Hello (props){
  const { className, children } = props;
  return (
    <div className={ className }>
      { children }
    </div>
  );
}

render((
  <Hello className="div">
    Hello World
  </Hello>
),document.getElementById('app'))

表达式

JSX{}用来表示一个JavaScript表达式,你可以在这里进行求值逻辑或者赋值,赋值且可看上述的Hello例子,只需要{ children }

且看我们已经实现的Dialog根据不同的type类型来呈现不同的子组件。

好的写法是将逻辑判断写在return之前(good):

import Alert from './Alert';
import Confirm from './Confirm';

class Dialog extends React.Component {
  render (){
    const { type } = this.props;
    const Component = type === 'alert' ? Alert : Confirm;
    return (
      <section>
        <Component {...this.props} />
      </section>
    );
  }
}

当然你也可以直接将表达式写在return里面(这个写法非常不好 bad):

import Alert from './Alert';
import Confirm from './Confirm';

class Dialog extends React.Component {
  render (){
    const { type } = this.props;
    return (
      <section>
        { type === 'alert' ? <Alert {...this.props} /> : <Confirm {...this.props} /> }
      </section>
    );
  }
}

注释

JSX里的注视和JavaScript一样,比如///**/,唯一的要求是需要使用{}包括起来。

{/*<Component {...this.props }/>*/}

spread attributes

在Dialog的例子中可以看见大量的...符号,这是属于ES2015规范中的操作符,在React组件中的{...this.props},可以将props的属性设置为React Component的属性。

HTML转义和自定义属性

为了防止XSS攻击,React组件会将需要显示到DOM的字符串进行转义,如果实在有这样的需求,可以有如下的几种方式解决:

  • 使用UTF-8的字符集
  • 使用对应字符的Unicode编码
  • 使用数组组装
  • 使用原始HTML
<div>{['First ', <span key="middot">&middot;</span>, ' Second']}</div>

如果你在JSX中使用了不存在于HTML规范的属性,这个属性是会被忽略的,你需要使用data-方式来自定义属性。

关于支持的标签,属性,以及可访问性属性前缀的列表:

results matching ""

    No results matching ""