1 简介

JSX(JavaScript XML),即可拓展的JavaScript,是react定义的一种类似于XML的js扩展语法:JS+XML。它本质上是React.createElement(type,config,...children)的语法糖,主要用于创建React元素,生成虚拟DOM

2 使用jsx

可以使用react脚手架或者引入react与babel相关脚本来体验jsx。
这里主要介绍一下后者如何使用

3 jsx语法规则

jsx包括xml格式的标签和jsx表达式{},下面从这两个角度来介绍jsx的语法规则

标签规则

  1. 根标签单一且闭合,否则抛出异常
  2. 标签类名使用className而非class,内联样式的属性名采用小驼峰形式命名
    const FC = () => (
        <h1 className="font-red">
            hello react
            <span style={{ color: 'blue' }} onClick={() => { alert('click span') }}>inner text</span>
        </h1>
    )
  1. 标签属性都可以使用jsx表达式{},只有字符串可以省略大括号
    <h1 className="font-red">
            hello react
    </h1>

jsx表达式规则

  1. {}中必须返回一个值
  2. 基于1,流程控制与循环语句语句如if、for是不允许的,因为他们默认没有返回值,而逻辑运算符如&&、||、三元表达式是允许的,函数也是允许的,因为它们一定会返回一个值。因此jsx中做逻辑判断的时候优先使用后者。
  3. 基于2,如果一定要使用if、for,考虑在jsx表达式中使用IIFE
    <input type="text" value={((type)=>{
        if(type === 1){
            return 'one'
        }else if(type === 2){
            return 'two'
        }else{
            return ''
        }
    })(type)} />
  1. 对于falsy值,0会被正常渲染到页面,而false,true,null,undefined不会。如果一定要渲染它们,请先转换成字符串。
    // 比如下面这段代码会在页面上显示一个不符合期望的0
    const FC2 = ({arr}) => <span>{arr.length && arr.join()}</span>
    ReactDOM.render(<FC2 arr={[]} />, document.getElementById('app'))

4 jsx优缺点

4.1 优点

js语法在运行时灵活的特性
基于js语法拓展,jsx具有js较为灵活的特点

xml在树状结构的表现上较为优秀
因为在嵌套层数较深、交互逻辑更复杂的情况下,xml+js比起js直接创建dom或CreateElement等方式来说更人性化、更易于维护

放止XSS DOM注入型攻击
jsx会将标签转义为字符串,以防止恶意标签被注入到页面

    // 页面上展示文案: <a href="#">inner text<\/a>
    const FC = ({value}) => <div>{value}</div>
    ReactDOM.render(<FC value={`<a href="#">inner text<\/a>`} />, document.getElementById('app'))
    // 页面上出现a标签,DOM被注入
    const FC = ({value}) => <div dangerouslySetInnerHTML={{__html:value}}></div>
    ReactDOM.render(<FC value={`<a href="#">inner text<\/a>`} />, document.getElementById('app'))

4.2 缺点

导致项目依赖增多
jsx必须依赖babel等编译工具转换成React.createElement才可以正常运行,导致项目依赖增多

5 深入react源码解读jsx到ReactElement

此后,jsx被编译成了React.CreateElement,后面要做的事情就是执行这个方法并创建React元素。对后续细节感兴趣可以看看这篇深入react源码解读jsx到ReactElement

发表回复