跳至主要内容

[note] JSX

  • JSX 元素的最外層,必須只能有一個根元件。
  • 在 JSX 中,所有自關閉標籤(self-closing tag)必須在最後加上 /,例如,<br />
  • 在 JSX 中,若要為元素代入樣式,需使用 className 屬性,例如,<div className="foobar">
  • 任何在 JSX 中的元素都會被視為 JSX,而非平常的 JavaScript,因此若在 JSX 元素中使用 JavaScript,會被當作字串直接輸出,若希望該段內容被當作 JavaScript 處理,需使用大括號 {} 包住。

代入 class 樣式

使用關鍵字 className

const container = <div className="container">Hello</div>;

代入行內樣式(inline style)

使用 {% raw %} {{ }} {% endraw %} 即可代入行內樣式,外面的大括號是一般在 React 中,用來告訴 JSX 這個部分裡面的內容是 JavaScript;第二個大括號比較的是物件所用的 { } ,所以實質上就是把一個物件代到 style 屬性內:

import React from 'react';
import ReactDOM from 'react-dom';

const styleMe = (
<h1 style={{ background: 'lightblue', color: 'darkred' }}>Please style me! I am so bland!</h1>
);

const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(styleMe);

另一種常見的方式則是定義一個名為 style 的變數,然後再把它插入到 JSX 的元素中,由於使用的是 JavaScript 的模組,因此除非你在模組內把該變數匯出(export),否則同樣名稱的變數並不會衝突:

import React from 'react';
import ReactDOM from 'react-dom';

const styles = {
background: 'lightblue',
color: 'darkred',
fontSize: 20, // 等同於 20px
marginTop: '60px',
};

const styleMe = <h1 style={styles}>Please style me! I am so bland!</h1>;

const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(styleMe);

在 React 中,多數的樣式如果沒有點寫單位,預設會自己幫你帶 px,完整支援的清單可在這裡檢視

代入 JavaScript 表達式

使用大括號 { }

const containerWithJS = <h1>2 + 3 = {2 + 3}</h1>;

代入屬性(attribute)

const pics = {
panda: 'http://bit.ly/1Tqltv5',
owl: 'http://bit.ly/1XGtkM3',
owlCat: 'http://bit.ly/1Upbczi',
};

const panda = <img src={pics.panda} alt="Lazy Panda" />;

const owl = <img src={pics.owl} alt="Unimpressed Owl" />;

const owlCat = <img src={pics.owlCat} alt="Ghastly Abomination" />;

綁定事件(event listener)

<img onClick={myFunc} />

 要特別留意的是,在一般的 HTML 中綁定事件是全部以小寫表示(lowercase),像是 onclick, onmouseover;在 JSX 中,綁定事件是以小駝峰命名(camelCase),例如 onClickonMouseOver

Supported Events @ React

if ... else ... 條件式

let message;

if (user.age >= drinkingAge) {
message = <h1>Hey, check out this alcoholic beverage!</h1>;
} else {
message = <h1>Hey, check out these earrings I got at Claire's!</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(message);

疊代元素

在 JSX 中有關鍵字 key 屬性(attribute),它就像 id 屬性一樣,需要是唯一的。

const strings = ['Home', 'Shop', 'About Me'];

const listItems = strings.map((string, i) => <li key={'list_' + i}>{string}</li>);

const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<ul>{listItems}</ul>);

在 JSX 中,可以直接代入一個一個的 list,也可以直接代入一個 array:

// This is fine in JSX, not in an explicit array:

<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>

// This is also fine!

const liArray = [
<li>item 1</li>,
<li>item 2<li>,
<li>item 3</li>
];

<ul>{liArray}</ul>

使用 React.createElement()

React.createElement() @ React

當 JSX 的元素被編譯過後,JSX 的元素會被轉換成在 React.createElement() 中的內容,每一個 JSX 元素其實都會呼叫 React.createElement() 這個方法:

// jsx
const h1 = <h1>Hello world</h1>;

被編譯成:

// jsx 會被編譯成這樣
const h1 = React.createElement('h1', null, 'Hello, world');
信息

也就是說 JSX element 其實只是呼叫 React.createElement 的語法糖,可以進一步參考 React Without JSX

使用 root.render

// const container = <div className="container">Hello</div>;
const container = <div className="container">Hello</div>;
const app = document.querySelector('#app');

const root = ReactDOM.createRoot(app);
root.render(container);
const foobar = 'Hello React';

const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<h1>{foobar}</h1>);

參考