有一對兄弟 class & function
class 很聰明,只是胖了一點。
function 呢,很懶,可是長的好看,他在某些時候甚至可以 a.k.a. PURE COMPONENT。
他們同樣都是 component 家族的一員。
昨天我們帶到 component 的時候,看到的是class component。
現在來重新定義一個 class component,並把它定義為 ElderBrother,再來好好講解一下吧!
class ElderBrother extends Component {
  render() {
    return (
      <div>
        <h1>我是 class</h1>
      </div>
    );
  }
}
而 function component 呢,架構很簡單,我們把它定義為 YoungerBrother。
function YoungerBrother() {
  return (
    <div>
      <h1>我是 function</h1>
    </div>
  )
}
為了避免搞混,我們就各別以 class component 和 function component 來稱呼他們
回到正題,這兩個看起來好像沒有太大的差別。
我們將 class component 加入 app.js 裡,會像這樣。
import React, { Component } from "react";
class App extends Component {
  render() {
    return (
    <div>
      <h1>Hello World</h1>
      <ElderBrother />
    </div>
  )
  }
}
class ElderBrother extends Component {...};
export default App;
註:這邊我為了節省版面,用 {...} 省略了重複的部分,如果有不清楚的部分歡迎提出。
歲月流逝,兩兄弟漸漸長大了,開始各自展現了自己的特色。
class component 因為比較聰明,他開始可以記得很多東西,所以他長出了一個東西,叫 constructor。
註:constructor (建構值),最重要的功能是可以儲存 state,就像大腦,也是當 component 被呼叫時第一個執行的區塊。
class ElderBrother extends Component {
  constructor(props){
    super(props)
    this.state={
      memory:'infinity'
    }
  }
  render() {
    return (
      <div>
        <h1>我是 class</h1>
      </div>
    );
  }
}
於是 class component 開始可以撰寫功能( function ),去執行他想達成的事。
例如改寫記憶。
class ElderBrother extends Component {
  constructor(props) {...}
//----->自訂的 function 放在這裡面<-------//
  handleChange() {
    this.setState({ memory: "i'm gooooood" });
  }
//----------------------//
  render() {...};
}
這時聰明的 class component 發現了問題。
他必須在 constructor 內綁定他的 function,他才能做事。
class ElderBrother extends Component {
    constructor(props) {
    super(props);
    this.state = {...};
//----------bind function-----------//
     this.handleChange = this.handleChange.bind(this);
//---------------------------------//
  }
  handleChange() {...}
  render() {...}
}
註:如果沒有使用 bind(this) 把此 function 指向到這個 class 的話會出現 undifine。白話一點就是 react 找不到啦,你要好好跟他說XD。至於為什會找不到,就會牽扯到 windows、global、local 的概念,這個部分未來會再額外做一篇講解。
class component 一整個就不爽了,這就代表每當他新增一個 function,他就要綁定一次,有沒有方法可以不要這樣做。
handleChange= () => {
  this.setState({ memory: "i'm gooooood" });
}
於是它找到了 ES6 釋出的黑科技 arrow function。
註:使用 arrow function 就會讓 this 自動綁定到定義它的 component,所以就不需要額外設定。
接下來我們在畫面上實做一個按鈕,操控畫面看看吧!
class ElderBrother extends Component {
  constructor(props){…}
  handleChange = () => {...}
  render() {
    return (
      <div>
        <h1>我是 class</h1>
	        <p>
		  <button onClick={handleChange}>change</button>
	    </p>
	   <h3>{memory}</h3>
      </div>
    );
  }
}
畫面會像這樣子
按下 change 試試看吧!
改變成功!我們已經可以透過 function 去改變 state 和顯示在畫面上了。
今天初步認識了 class component 的構造 ,並且可以透過撰寫 arrow function 去改變 state,但其實 class 還有一個可以撰寫的區域-生命週期,我們將會在未來的幾篇內做介紹。
我是 Chris 明天將繼續介紹另外一個 component -function component 並稍微帶到不同 component 之前傳遞 state 的方法,明天見~