認識 JSX 和 Component 特性
- Published on
- modern-react-with-redux
認識 JSX
前面說過元件會回傳 JSX,JSX 不是新的語言,它只是 React 提供的語法糖,開發 React 並不一定要使用 JSX,它只是讓我們能更方便、快速建立 HTML 內容(並非真的在撰寫 HTML),瀏覽器是無法辨識 JSX 的,所以需要經由 babel 轉換成正常的 JavaScript 來執行。
用 https://babeljs.io/ 進行測試,可以發現這段 JSX 會被 babel 變成下面的形式
呼叫 React.createElement 方法
- 第一個參數,要創建的元素類型,例如 div、input、img 等等
- 第二個參數,object,放入該元素的屬性
- 第三個參數,元素裡面要放的內容 text
// before
const Button = () => {
return <button type="button">submit</button>
}
// after babel
const Button = () => {
return React.createElement(
'button', // the type of element
{ type: 'button' }, // the properties of element
'submit' // the text to show inside the element
)
}
和 html 的不同
- 添加樣式的方式
- 要寫 inline-style 得使用
{{}}
,外層括號表示要在 JSX 引入 JavaScript 變量 - 內層括號,放 JavsScript 物件
- JSX 內的標籤、名稱等一般字串是用雙引號,對於非 JSX 的變數建議使用單引號
- 要寫 inline-style 得使用
- 不要使用 class、for 或某些屬性名稱
React 會查看元素的一些屬性
偶爾你可能會在 devTool 看到 invalid property
的提醒字樣,這是因為那些字在 JavaScript 中屬於 keyword,像是 class、for 等等,為了避免衝突所以一律使用 className
、htmlFor
及其他 React 建議的文字代替
- 可以引用 JavsScript 的變量,用
{}
包裹起來
基本上在 JSX 裡面要使用到 JavaScript 變量,就是用 {}
來標示,可以放入變數、甚至放執行 function 後的結果
function getTime() {
return new Date().toLocaleTimeString()
}
const App = () => {
return (
<div className="container">
<div>Current Time:</div>
<h3>{getTime()}</h3> // 使用 getTime 執行的結果作為變量
</div>
)
}
component 的三個特性
Component Nesting
- 將 JSX 拆出來變成一個元件,給予一個好的、有意義的名字
- 在
./component
資料夾底下新建一個檔案來寫,檔名和元件名稱一樣(都以大寫開頭)- 寫好元件,把它 export 出去
- 在 import 時,後面不需要加上 .js 或副檔名,webpack 會自動幫你處理這塊
- 不用另外寫
{}
,在一個元件裡面放另一元件時只需要使用 JSX tag 包起來
Component Configurable
當 App
是用來顯示下面的 CommentDetail
、或說 CommentDetail
被崁套在 App
時,我們會稱上層是父元件、下層的是子元件,這就是元件的層級架構(Component Hierarchy)。
而「Props(Properties) System」指的是將 data 從父元件傳遞到子元件的機制,讓子元件的顯示內容和行為可以被父元件決定:
- 父元件提供東西給子元件
跟設定 HTML 屬性很相像,在元件上寫 props 名稱及它對應到的 value,可以自行定義 props 的名稱,像是 author="Sam"
、author="Alex"
每個子元件都是獨立存在,有同樣的屬性名稱,但接受到父層傳遞不同 value,並不會跟其他子元件共用,當我們使用 JSX tag 創建子元件時,實際上是創造一個新的 compoenent instance。
const App = () => {
return (
<div>
<CommentDetail author="Sam" />
<CommentDetail author="Alex" />
<CommentDetail author="John" />
</div>
)
}
- 子元件接收父層的東西
function component 第一個參數是名為 props
的物件,裡面放著從父元件傳遞過來的所有資訊,以 key-value 形式存在,可以直接拿、或是先經過解構
const CommentDetail = (props) => {
console.log(props) // { name: 'Sam' }
return (
<div>
<p class="comment__name">{props.name}</p>
</div>
)
}
Component Reusable
還有另一個特別的屬性,同樣能傳遞東西給到子元件。
當今天 component 不是使用 self-closing tag,而是有嵌套其他元素或元件時,它裡面包裹的東西會以「children」屬性存在 props 中,所以我們能利用這項特性,做到抽換內容、讓元件重複使用。
const ApprovalCard = (props) => {
return (
<div>
<div class="card__conttent">{props.children} // 會是 ComponentDetail 這個元件</div>
<button class="card__green_btn">Agree</button>
<button class="card__red_btn">Reject</button>
</div>
)
}
const App = () => {
return (
<ApprovalCard>
<CommentDetail author="Sam" content="Nice blog post!" avatar={faker.image.avatar()} />
</ApprovalCard>
)
}
其他參考資料:React 和 ReactDOM 的區別