Component的概念就很像一塊塊積木,可以拼湊組成城堡或是飛船之類的,Component裡頭會回傳React element,透過這些Component就可以組成網頁的UI畫面,可以依照需求來切分不同功能的Component,一個Component結構可以很簡單,裡面甚至只有一個按鈕,這時候就會有個疑問?拆分的這麼細有什麼好處嗎?最大的好處就是相似的結構可以抽離出來重複使用,不需要重複的邏輯寫好多遍,也方便維護,有了Component就可以解決以下的問題:
情境一
傳統的寫法為每個頁面都有一個header,假設網頁的header需要改動,就要打開每個頁面header調整,真的會吐血..
情境二
a頁面、b頁面、c頁面都需要這個按鈕,然後功能還一模一樣,重複的東西居然要寫三遍…
Component會定義這個組件的結構樣式等等,再透過外部傳進的資料,根據資料的變化,來更動UI畫面,不需要像傳統那樣手動更新。React Component的有兩種寫法 Class Component以及 Functional Component,今天先來介紹Class component,利用 ES6 Class的語法來創建Class Component,既然提到了Class就花點時間稍微簡介一下Class有哪些方法吧!
在Class 物件被建立時會呼叫一次,物件的屬性會在這裡做定義,這裡也可以帶入不同的參數來建立不同的類別,那可以不寫嗎?答案是可以的,沒寫也會預設幫你創建constructor
class Bird{
constructor(name){
this.name = name
}
}
const bird1 = new Bird('kerry')
const bird2 = new Bird('bay')
先宣告一個父類別(鳥類),並且一定義一個飛行的函式,接者子類別(老鷹)繼承父類別,就可以使用父類別定義的方法。
class Bird{
fly(){
console.log('fly')
}
}
class Eagle{
}
const eagle = new Eagle()
eagle.fly() // 印出fly
假如子類別定義了與父類別相同的函式名稱,那麼子類別的函式就會取代父類別的函式
class Bird{
fly(){
console.log('Birdfly')
}
}
class Eagle{
fly(){
console.log('Eaglefly')
}
}
const eagle = new Eagle()
eagle.fly() // Eaglefly
那假設我想要在子類別的呼叫父類別的方法可以嗎?就是super()登場的時候了,為了可以取得父類別的屬性或是方法會在constructor呼叫super()方法,這麼一來子類別不需要重寫一遍this.name = name,只要super(name)即可,利用super.函式名稱就可以呼叫父類別的方法。
class Bird{
constructor(name){
this.name = name
}
fly(){
console.log('Birdfly')
}
}
class Eagle{
constructor(name){
super(name)
}
fly(){
super.fly()
console.log('Eaglefly')
}
}
const eagle = new Eagle()
eagle.fly() // 輸出Birdfly Eaglefly
屬於class的屬性或方法,不需要實例化,就能以 class名稱.方法來呼叫
class Bird(){
static diss(name){
console.log('diss ' + name )
}
}
Bird.diss('mel') //輸出diss mel
const bird = new Bird()
bird.diss('mel) //bird.diss is not a function
了解了Class類別之後就可以來創建React Component,要先import React Component
import React, { Component } from 'react';
然後宣告一個Class,記得命名要跟檔名一致,第一個字都為大寫,並且繼承React Component
class ComponentExample extends Component{
constructor(props){
this.super(props)
this.state = { count: 0 }
}
render(){
return(
<div>
<h1>{this.props.name}</h1>
</div>
)
}
}
export default ComponentExample
constructor() 方法,必須先執行super(),才能取得this,會在這裡設定state的初始值,在參考範例的時候,我發現了一件事,為什麼有的範例有寫super(props),有的沒有呢? 而且沒寫的話在render也可以拿到this.props,查了資料原來不管有沒有寫super(props),在render階段都可以用this.props
剛好在爬文的時候看到有網友分享有沒有加super(props)的差異,個人覺得蠻清楚的
什麼都沒寫的
constructor() {
super()
console.log(this.props)//undefined
console.log(props)//error
}
無法取得 this.props
constructor(props) {
super()
console.log(this.props)//undefined
console.log(props)//{}
}
成功取得this.props!
constructor(props) {
super(props)
console.log(this.props)//{}
console.log(props)//{}
}
這樣看起來如果要在constructor階段取得this.props還是乖乖寫上super(props)吧!
render為React Component一定要實作的的方法不然會報錯,會回傳一個使用JSX 生成的React Elements,每當props、state變化時就會觸發一次
明天會接著繼續介紹 Functional Component 與 Class Component 的差異