所謂元件,即封裝起來的具有獨立功能的 UI 部件。React 推薦以元件的方式去重新思考 UI 構成,将 UI 上每一個功能相對獨立的子產品定義成元件,然後将小的元件通過組合或者嵌套的方式構成大的元件,最終完成整體 UI 的建構。
元件,從概念上類似于 JavaScript 函數,接收任意的入參(稱為 props),并傳回用于描述頁面展示内容的 React 元素。
React 元素可以是 DOM 标簽,也可以是使用者自定義的元件。React 會将以小寫字母開頭的元件視為原生 DOM 标簽。自定義元件名稱必須以大寫字母開頭。// HTML 标簽 const element = <div /> // 自定義元件 const element = <Welcome />
子產品、子產品化群組件、元件化:
子產品、子產品化:
子產品:向外提供特定功能的 JS 程式,一般就是一個 JS 檔案。
子產品又可以稱為 JS 子產品,就隻是拆分 JS。
拆分子產品的原因:随着業務邏輯增加,代碼越來越多且複雜。
子產品的作用:複用 JS;簡化 JS 的編寫;提高 JS 運作效率。
當應用的 JS 都以子產品來編寫的,這個應用就是一個子產品化的應用。
元件、元件化:
元件:用來實作局部功能效果的代碼和資源的集合(HTML、CSS、JS、圖檔、音視訊、字型 等)。
拆分元件的原因:一個界面的功能複雜。
元件的作用:複用編碼;簡化項目編碼;提高運作效率。
當應用是以多元件的方式實作,這個應用就是一個元件化的應用。
定義元件:
- 函數式元件:函數名就是元件名,适用于簡單元件的定義。
如果元件沒有狀态 state,那就是簡單元件。
函數式元件中沒有 this。
函數式元件不能使用 state、refs(props 可以作為函數的參數傳入,是以可以使用)。
函數式元件沒有生命周期。
function Welcome(){ return <h1>Hello</h1> // 必須有傳回值,傳回值可以是 JSX 對象或 null }
- 類元件:類名就是元件名。React 中的類元件必須繼承 React 中的内置元件 Component。适用于複雜元件的定義。
如果元件有狀态 state,那就是複雜元件。
class Welcome extends React.Component { render() { return <h1>Hello</h1> } }
渲染元件:
- 函數式元件:
執行function Welcome() { // 函數式元件中通路 this 會得到 undefined // 原因是:通過 Babel 編譯後開啟了嚴格模式,嚴格模式中禁止自定義函數中的 this 指向 window return <h1>Hello</h1> } ReactDOM.render(<Welcome/>, document.getElementById('root'))
,發生了什麼?ReactDOM.render(<Welcome/>, document.getElementById('root'))
- React 解析元件标簽,找到了 Welcome 元件。
- 發現 Welcome 元件是使用函數定義的,随後調用該函數,将傳回的虛拟 DOM 轉為真實 DOM,呈現在頁面中。
- 類元件:
執行class Welcome extends React.Component { render(){ // render 被放在 Welcome 的原型對象上,供執行個體使用 // render 中的 this 是 Welcome 元件執行個體對象 return <h1>Hello</h1> } } ReactDOM.render(<Welcome/>, document.getElementById('root'))
,發生了什麼?ReactDOM.render(<Welcome/>, document.getElementById('root'))
- React 解析元件标簽,找到了 Welcome 元件。
- 發現 Welcome 元件是使用類定義的,随後 new 出來該類的執行個體,并通過該執行個體調用原型上的 render 方法。
- 将 render 傳回的虛拟 DOM 轉為真實 DOM,呈現在頁面中。
隻有類元件才有執行個體對象,元件執行個體有三大核心屬性:state、props、ref。函數式元件都通路不到 this,自然也就沒有執行個體對象。
類元件的執行個體對象:
組合元件:
元件可以在其輸出中引用其他元件。
function Parent() {
return <Child name="Sara" />
}
function Child(props) {
return <h1>Hello, {props.name}</h1>
}
提取元件:
将元件拆分為更小的元件。
類元件中的構造器 constructor():
通常,在 React 中,構造函數 constructor() 僅用于以下兩種情況:
- 通過給 this.state 指派對象來初始化内部 this。
- 為事件處理函數綁定執行個體。
在 React 元件挂載之前,會調用它的構造函數。在為 React.Component 子類實作構造函數時,應在其他語句之前調用
super(props)
,否則,this.props 在構造函數中可能會出現未定義的 Bug。
如果不初始化 state 、不為事件處理函數綁定執行個體或者使用簡寫的方式初始化 state、通過指派語句加箭頭函數的方式的為事件處理函數繼承執行個體,則不需要為 React 元件實作構造函數。
總而言之:
- 類元件中的構造器是可以省略的。
- 如果寫了構造器,構造器是否接收 props,是否傳遞給 super,取決于是否希望在構造器中通過 this 通路 props。
class Weather extends React.Component{
constructor(props) {
super(props)
// 初始化 state
this.state = {
isHot: false,
}
// 為事件處理函數綁定執行個體
this.changeWeather = this.changeWeather.bind(this)
}
// 簡寫的方式初始化 state
state = {
isHot: false,
}
// 通過指派語句加箭頭函數的方式的為事件處理函數繼承執行個體
changeWeather= () => {}
}