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()這個方法。
參考鏈接: