React (2) JSX 解說

什麼是 JSX ?

JSX(JavaScript XML)是一種在 React 中常用的語法擴充,它允許你在 JavaScript 中撰寫類似 HTML 的代碼。
JSX 的語法非常類似於 HTML,但它實際上是在 JavaScript 中運行的語法糖。JSX 會被 React.createElement() 函數調用,這些函數創建了 React 元素。

1
2
3
function App() {
return <h1>React 我來了 <small className="text-danger">{new Date().toLocaleDateString() }</small></h1>
}

會被 Babel 編譯為

1
2
3
4
5
6
7
8
9
10
11
function App() {
// 標籤、HTML屬性、
return React.createElement(
'h1', null, 'React 我來了',
React.createElement('small', {
className: 'text-danger',
title: '時間'
}, new Date().toLocaleDateString()),
'結尾'
);
}

JSX 呈現內容注意事項

物件

在 JSX 中無法帶入物件型別

1
2
3
4
const data = {
name: '小明'
}
{ data } // 無效

如果真的想查看整筆物件資料,可以先轉成字串,但僅限於開發中查看使用

1
2
3
4
const data = {
name: '小明'
}
{ JSON.stringify(data) }

布林值

在 JSX 中無法呈現布林值在畫面上

1
{ true } // 無效

如果真的想呈現布林值在畫面上,可以用三元運算式

1
{ true ? 'true' : 'false' }

undefined null

undefined 跟 null 無法用 jsx 呈現在畫面

1
2
{ undefined } // 無效
{ null } // 無效

陣列

陣列的內容會直接呈現到畫面上

1
2
3
4
5
6
7
8
9
10
11
const list = [
<li className="list-group-item">An item</li>,
<li className="list-group-item">A second item</li>,
<li className="list-group-item">A third item</li>,
<li className="list-group-item">A fourth item</li>,
<li className="list-group-item">And a fifth one</li>
];

return <ul className="list-group list-group-flush">
{ list }
</ul>

JSX 與 HTML 標籤屬性

class

jsx 中 class 要改為 className

1
{<div><button type="button" className="btn btn-primary">Primary</button></div>}

style

在 jsx 中加入行內樣式,必須使用物件帶入

  • 屬性名稱: 要用小駝峰撰寫
  • 值: 要用字串格式
1
2
3
4
5
6
7
8
9
<div className='card-img-top'
style={{
height: '200px',
backgroundImage: `url('https://images.unsplash.com/photo-1564564321837-a57b7070ac4f?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=2352&amp;q=80')`,
backgroundSize: 'cover',
backgroundPosition: 'center center',
}}
>
</div>

checked 與 結尾標籤

jsx 中元素都要有結尾標籤,checked 屬性要改為 defaultChecked

1
{<div><input type="checkbox" defaultChecked /></div>}

value

input 標籤的 value 要改為 defaultValue

1
{ <div><input type="text" defaultValue="卡斯伯" /></div> }

for

input 的 for 標籤要改為 htmlFor

1
{ <div><input type="text" htmlFor="name" /></div> }

select

正常的 html 裡,select 要做預設值時,會加上空的 select

1
2
3
4
5
<select name="" id="">
<option value="1">1</option>
<option value="2" selected="">2</option>
<option value="3">3</option>
</select>

在 jsx 中則要改為 defaultValue

1
2
3
4
5
<select name="" id="" defaultValue="2">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>

textarea

jsx 中 textarea 可以不加入結尾標籤,並且預設文字要用 defaultValue 帶上。

1
<textarea name="" id="" cols="30" rows="5" defaultValue="我是預設文字" />

html 結構無法直接渲染

因為安全性問題,html 結構無法直接渲染在 jsx 裡。

1
2
3
4
5
const htmlTemplate = '<div>這裡有一段文字</div>'
<div>
{/* 會被當作純字串呈現 */}
{ htmlTemplate }
</div>

要使用 dangerouslySetInnerHTML 來加入,並且原始結構要加在物件的 __html 屬性裡。

1
2
3
4
const htmlTemplate = {
__html:'<div>這裡有一段文字</div>',
}
<div dangerouslySetInnerHTML="htmlTemplate"></div>

onChange

想要取得 input 元素的資料時,可以使用 onChange 屬性,並帶入 function,用 event.target.value 取得值。

1
2
3
4
5
<input type="text" onChange={
function(event) {
console.log(event.target.value)
}
}/>

JSX 與 JS

在 JSX 中可以用 { } 來帶入 js 變數資料, { } 中必須是 js 的表達式

1
2
3
4
5
6
7
8
9
10
11
export default function Avatar() {
const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
const description = 'Gregorio Y. Zara';
return (
<img
className="avatar"
src={avatar}
alt={description}
/>
);
}

JSX 常見錯誤

  • 元件要大寫:

定義元件要用大寫開頭,小寫會出錯

1
2
3
4
// 錯誤格式
function app() {
return <h1>React 我來了</h1>
}
  • 最外層只能有一個元素:
1
2
3
4
5
6
7
8
9
10
11
12
13
// 錯誤格式
function App() {
return <h1>React 我來了</h1>
<h2>React 我來了</h2>
}

// 正確
function App() {
return <div>
<h1>React 我來了</h1>
<h2>React 我來了</h2>
</div>
}

如果不想要多加一層元素來包,可以用 React.Fragment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function App() {
return <React.Fragment>
<h1>React 我來了</h1>
<h2>React 我來了</h2>
</React.Fragment>
}

// 或使用縮寫,就是省略 React.Fragment

function App() {
return <>
<h1>React 我來了</h1>
<h2>React 我來了</h2>
</>
}
  • 元素要有結尾標籤:

像 input 、 option 這類本身沒有結尾標籤的符號,要加上結尾標籤

1
2
3
4
5
6
7
8
9
10
11
12
13
function App() {
return <div>
<label for="exampleDataList" class="form-label" style="color: var(--bs-blue)">Datalist example</label>
<input class="form-control" list="datalistOptions" id="exampleDataList" placeholder="Type to search..." />
<datalist id="datalistOptions">
<option value="San Francisco" />
<option value="New York" />
<option value="Seattle" />
<option value="Los Angeles" />
<option value="Chicago" />
</datalist>
</div>
}