本文從「爲何不能直接在 JSX
裏面寫 console.log
」這個問題出發,分析了 React
的元素渲染機制,並介紹了幾種在JSX
執行 console.log
語句的姿式,最後還介紹了 React
項目中調試代碼的其餘姿式。javascript
本文適合 React
初學者閱讀,若是你已經能夠熟練使用 React
開發項目,本文對於你來講可能過於簡單。html
爲何會寫這篇文章呢?由於前一陣子在給公司裏面其餘同事(非前端)作 React
開發培訓的時候,發現有不少 React
初學者喜歡在代碼中使用 console.log
來調試,而且習慣性地寫成下面這樣:前端
// 這裏咱們指望將 menus 這個數據打印出來查看
return (
<div> <h1>Hello World</h1> console.log(menus) </div>
)
複製代碼
可是上面這個寫法 React
能讓你經過嗎?java
答案是否認的。讓咱們來看看這樣寫實際上會渲染出什麼效果:react
這顯然不符合咱們最初的預期——將 menus
數據顯示在頁面中,讓咱們能夠看到 menus
中具體有些什麼數據。web
那麼爲何會出現這種結果呢?chrome
這就要從 React
的元素渲染機制提及了。api
首先來看看對於<h1>Hello World<h1>
這個語句,React 是怎麼渲染的:數組
React.createElement(
'h1',
null,
'Hello World'
)
複製代碼
怎麼理解上面這段代碼呢?瀏覽器
JSX 是一個JavaScript
的語法擴展,咱們利用JSX
這個語法糖來更好地描述 UI
和數據的交互形式。可是咱們最終要交給瀏覽器去渲染的,應該是html
文件,這纔是瀏覽器能識別的,因此咱們須要利用 Babel 來作語法轉譯。
Babel
會把 JSX
轉譯成一個名爲React.createElement() 的函數調用。
讓咱們來看看 React.createElement()
函數的參數定義:
React.createElement(
type,
[props],
[...children]
)
複製代碼
它接收的第一個參數是 html
的標籤名,第二個參數是 props
,第三個參數就是標籤包裹着的全部 children。
好了,理解了 React
的元素渲染機制以後,咱們再來看看加上console.log
以後,完整的渲染語句:
render() {
return React.createElement(
'div',
null,
React.createElement(
'h1',
null,
'Hello'
),
'console.log(menus)'
)
}
複製代碼
能夠看到,對於 div
標籤來講,它的孩子有兩個:由h1
標籤包裹的 Hello World
文本<h1>Hello World<h1>
以及沒有任何標籤包裹的 console.log(menus)
文本(是的!在這裏,console.log(menus) 語句已經被 React.createElement 函數識別成了 文本!!!)。
因此,Babel
轉譯後交給瀏覽器渲染的節點就是下面這樣的:
如今,咱們再回過頭來看文章開頭的那個渲染結果就一點都不奇怪了。
以上的 Babel 轉譯過程你能夠點擊這裏來體驗
哼,雖然搞懂了爲何不能在JSX
中直接使用 console.log
這個打印語句來打印數據,可是有的時候咱們就是想要把數據打印出來調試(大部分前端 er 都習慣使用console.log
來調試代碼 ),怎麼辦呢?
還真有幾個好辦法,下面就聽我細細道來。
第一種方法最簡單了,應該你們都想獲得——你能夠在JSX
以外寫 console.log
啊。
render(){
console.log(menus)
return console.log(menus) || (
<div> <h1>Hello World</h1> </div>
)
}
複製代碼
若是你要打印的數據是對象或者數組,你還可使用 console.table
這個API 來打印,效果更佳:
首先咱們要明確一個點:
在
JSX
語法中,你能夠在大括號內放置任何有效的 JavaScript 表達式。例如,2 + 2
,user.firstName
或formatName(user)
都是有效的 JavaScript 表達式。
因此,你能夠這樣寫:
render(){
return (
<div> <h1>Hello World</h1> { console.log(menus) } </div>
)
}
複製代碼
這個方法就比較秀了,雖然不難也不復雜,可是通常人可能想不到。
咱們能夠這樣寫:
render(){
return console.log(menus) || (
<div> <h1>Hello World</h1> </div>
)
}
複製代碼
好了,看看瀏覽器渲染結果:
正確!沒有渲染出什麼咱們不想要的東西。
再看看控制檯:
也按照咱們的預期打印出了 menus 數據!
爲何能夠這樣寫呢?
由於 console.log
的返回值是 undefined,咱們能夠巧妙地利用這一點再結合 || 操做符短路的屬性,天然而然地實現既打印數據又正確渲染 UI 的效果。
JSON.stringify
第二種方法就是咱們能夠直接用JSON.stringify
將數據包裝一下,而後放在 div
標籤中渲染,這樣咱們就能夠直接在界面上看到數據,而不用一直盯着控制檯。
render(){
return console.log(menus) || (
<div> <h1>Hello World</h1> <div>{JSON.stringify(menus)}</div> </div>
)
}
複製代碼
固然,這種方式更適合於打印比較小的數據。
若是你已經看到了這裏,恭喜你!你已經掌握了四種在 React
使用執行 console.log
語句的姿式了~
不過使用 console.log
終歸不是一種優雅的方式,下面簡單介紹幾種 React 項目調試代碼的方式:
由於篇幅關係這裏就不展開講了,感興趣的同窗能夠點擊連接進去看下官方文檔瞭解下。