和我一起实战 react 之 JSX

2,302 阅读2分钟

我们知道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

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 (
    
{ children }
); } render(( Hello World ),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 (
      
        
      
    );
  }
}

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

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

class Dialog extends React.Component {
  render (){
    const { type } = this.props;
    return (
      
        { type === 'alert' ?  :  }
      
    );
  }
}

注释

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

{}

spread attributes

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

HTML转义和自定义属性

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

  • 使用UTF-8的字符集
  • 使用对应字符的Unicode编码
  • 使用数组组装
  • 使用原始HTML
{['First ', ·, ' Second']}

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

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