jsx

jsx是我们学习react第一个碰到的新概念,也是react被称为难上手的一个原因,也有很多人将jsx称为js xml,那么到底jsx是什么呢?我们来看官网:it is a syntax extension to JavaScript,它是一个js语法的扩展,那么它扩展的原理是什么呢,我们从一个例子来入手。

<div id='app'>
    <p>jsx</p>
</div>

我们思考一下怎么用JavaScript 对象来表现上面这个DOM 元素的结构,仔细分析可以知道每个dom都可以用一个对象表示,每一个dom所包含的信息无非三个:标签名、属性、子元素。

所以其实上面这个 HTML 所有的信息我们都可以用合法的 JavaScript 对象来表示:

{
  tagName:'div',
  props:{id:'app'},
  children:[
      tagName:'p',
      props:null,
      children:['jsx']
  ]
}

你会发现,HTML 的信息和 JavaScript 所包含的结构和信息其实是一样的,我们可以用 JavaScript 对象来描述所有能用 HTML 表示的 UI 信息。但是用 JavaScript 写起来太长了,结构看起来又不清晰,用 HTML 的方式写起来就方便很多了。

于是 React.js 就把 JavaScript 的语法扩展了一下,让 JavaScript 语言能够支持这种直接在 JavaScript 代码里面编写类似 HTML 标签结构的语法,这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换成 JavaScript 的对象结构。

import React, { Component } from 'react'
import ReactDOM from 'react-dom'

class App extends Component {
  render () {
    return (
     <div id='app'>
        <p>jsx</p>
    </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

经过编译以后会变成:

import React, { Component } from 'react'
import ReactDOM from 'react-dom'

class App extends Component {
  render () {
    return (
     React.createElement(
        "div",
        {id:'app'}
        React.createElement(
          "p",
          null
          "jsx"
        )
      )
    )
  }
}

ReactDOM.render(
  React.createElement(App, null), 
  document.getElementById('root')
);

React.createElement 会构建一个 JavaScript 对象来描述你 HTML 结构的信息,包括标签名、属性、还有子元素等。这样的代码就是合法的 JavaScript 代码了。所以使用 React 和 JSX 的时候一定要经过编译的过程。这也就解释了为什么我们写任何组件的时候都要引入React,明明有时候我们没用到React,其实React帮我们编译了jsx,而jsx在每个react组件都必不可少,所以我们编写组件的时候肯定需要引入React。

这个时候看jsx就没有那么纠结了,其实它就是一个对象,只不过用jsx这种结构表示的比较简洁,所以react就将用了jsx来表示对象,也有可能是很多人以讹传讹将jsx传言为js + xml,弄的很多人以为jsx很难而产生了畏难情绪,实际上我们完全可以把它认作一个对象,对象能做的事它都能做,所以我们就可以理解为什么jsx可以像对象那样自由地赋值给变量,或者作为函数参数传递、或者作为函数的返回值。

const app = <div id='app'></div>
function returnApp(){
    return app
}

可能还有人有疑惑,那为什么jsx会出现这些我们从未见过的标签,比如<App />、<Todo />,其实react用开头字母大小写来区分元素和组件,<App />其实是一个组件,编译过程如下:

class App extends React.Component {
  render() {
    return React.createElement(
            "div",
            {id:'app'},
            null
        )
  }
}

ReactDOM.render(
  React.createElement(App, {id: 'app'}, null),
  document.getElementById('root')
);

其实react编译组件的时候会将组件的类名作为jsx的名称,所以这个也导致了我们认为jsx是js+xml,其实它的本质还是用了React.createElement()这个方法。

参考链接:

使用 JSX 描述 UI 信息

React Without JSX

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容