React.js快速入門 — (4)Component
Component — React.js最小組成,針對16.8版後的React.js所製作的新手入門上手文章
在上一篇文章:React.js快速入門 — (3)JSX,介紹了JSX的使用方式並且哪些坑應該避免。JSX就是協助用來負責建立Element的。Element跟Component差別又在哪裡呢?
在官方描述是說,Component是:
Component 可以讓你把 UI 切分為獨立並可重複使用的單位,並且每個單位可以抽出來獨立思考
Element則是:
來描述你的 UI 應該長成什麼樣子
註:UI指的是使用者介面,也就是網頁畫面呈現的樣子。
React Element
建立 React 應用程式最小的單位是 element。Element 是由 component 所「組成」的。
亦即Element由一個或以上的Component組成的,Component就是將很多功能做能重複使用的函式模組化,組成起來並且能夠輸出到網頁的叫做Element。
JSX 標籤的第一個部分決定 React element 的類型。
任何的React Element最上層節點只能有一個:
//可以輸出
ReactDOM.render(
(<div>
<h1>Hello, world!</h1>
<h2>Brian</h2>
</div>),
document.getElementById('root')
);//不能輸出
ReactDOM.render(
(<h1>Hello, world!</h1>
<h2>Brian</h2>),
document.getElementById('root')
);
順帶一提,若你期望要能實現上面”不能輸出”的東西,必須使用React Fragments。這份教學不會使用到,請安心繼續服用。
Component原則
- Component就是基於Javascript的函式,呼叫Component可以使用
props
傳遞參數,props
的細節將在下一篇分析。只是在回傳的時候是用JSX或是React Element方式傳遞。
例如:function Hello(props){return <H1>{props.sendData}</H1>;}
- 依照React.js規定,Component的函式命名的字首須為大寫字母,傳遞參數的時候是依照camelCase。例如:
<Hello sendData="mynameishello"/>
- Component最高層通常都有一個名為App Component。例如:Create-React-App的
app.js
檔案綁到index.js
,也像是(2)Overview章節提到的「會綁定最高層的Component」,只是index.html
也寫成index.js
。
Component有分成兩大種類 — Function形式與Class形式,以及一個合成屬性 — Composition。
Function Component
用Function包覆想要 render
的內容。
function Welcome(props){
return <h1>Hello, {props.userName}</h1>;
}
最後要 render
的時候需要呼叫 reactDOM.render()
協助輸出到網頁上。
ReactDOM.render(
<Welcome userName="World"/>
document.getElementById('root')
);
(ES6) Class Component
用Class包覆所有需要的函式,包括 render
也寫在裡頭。它的存在是要配合 state
的儲存以及生命週期的處理, state
將在下一篇介紹。
class Welcome extends React.Component{
constructor(props){
super(props);
}
render(){
return <h1>Hello, {this.props.userName}!</h1>
}
}
宣告一個 class
然後繼承 React.Component
取得 Component 一些功能函式。 props
的部分必須要先在 constructor()
建構式使用 super
向React.Component
綁定,呼叫class的時候constructor
就會自動啟動。
最後當有任何更新的時候都會自動呼叫 render()
執行。
不過自從 hook
的出現,React.js 也推薦開始少用 Class Component,因為 hook
已經協助包辦堪稱 Javascript 最大障礙:Class的 this
問題以及 state
生命週期的整合,這些都會在下一篇完整介紹。
Element接Element
在還沒有要 Render
之前,我們可以不斷組合Component成一個Element再給另一個Element接,最後再呈現到網頁上。
假設我們有三個檔案 Main.js
、 TodoHeader.js
、 TodoList.js
都在同一個資料夾。
TodoHeader.js
:
const TodoHeader = ()=>(
<div>
<h1>TodoHeader</h1>
</div>
);
export default TodoHeader;
TodoList.js
:
const TodoList = ()=>(
<div>
<h1>TodoList</h1>
</div>
);
export default TodoList;
Main.js
就將這兩個檔案做import,並且引用然後輸出到網頁:
import TodoHeader from './TodoHeader'
import TodoList from './TodoList'
ReactDOM.render(
(<div>
<TodoHeader/>
<TodoList/>
</div>),
document.getElementById('root')
);
如此一來就可以把Element跟Element連接在一起。
()=>()
:是Arrow function,是 function(){return ();}
的簡寫
有關 import
與 export
或 export default
的跨檔案引入問題,可參考openhome.cc的介紹。
Composition
有些 component 不會提早知道它們的 children 有些什麼。對於像是
Sidebar
或Dialog
這類通用的「box」component 特別常見。
在上一張有提到JSX的Children可傳遞下去給Component,我們在Component運用Children的內容稱之為Composition。
上層:
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
下層:
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
會將上層粗體字傳到 props.children
裡頭。
更多使用方式,請整系列觀看完後詳見官方文本。
結語
此環節是React.js最重要的部分,因此著墨不少地方,把這裡慢慢消化再繼續前往下一篇:如何在Component儲存我要的資料。
喜歡的話可以給我一點掌聲唷!
上一篇:React.js快速入門 — (3)JSX
下一篇:React.js快速入門 — (5)Prop&State&Hook