30DaysChallenge 是自主性每兩天寫一篇技術相關的部落格
React
Class-based
React 中其實有另一種寫法,class-based
在 Hook 出現以前較常遇見
example from here
class Clock extends React.Component {
constructor(props) {
super(props)
this.state = { date: new Date() }
}
componentDidMount() {
this.timerID = setInterval(() => this.tick(), 1000)
}
componentWillUnmount() {
clearInterval(this.timerID)
}
tick() {
this.setState({
date: new Date(),
})
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
)
}
}
ReactDOM.render(<Clock />, document.getElementById("root"))
而在 16.8 之後出現的 Hook,像是 useState、useEffect 其實與上方的概念的類似,只是名詞不同,使用的地方也不同。
順帶一提,Hook 不能使用在 class-based。
那跟生命週期有甚麼關係呢?
生命週期
生命週期簡單來說就是 React 渲染畫面時,會怎麼執行,可以想像成有一套渲染的 SOP。
透過上圖,可以知道
- 第一次進入畫面時,先把該弄的資料弄一弄,然後
render
componentDidMount
也就是當元件渲染完成了之後,會執行的其他動作
- 會依照
其他動作
,看要不要重新渲染畫面 componentDidUpdate
當特定的資料改變時,要執行的動作componentWillUnmount
也就是當元件從 DOM 消失,要執行的動作
了解這些步驟後,是不是跟某個 hook 很相像呢?
沒錯! 就是 useEffect!
useEffect 的確就是
- 第一次進入畫面,渲染完後,執行
useEffect
裡面的動作 - 爾後,如果
useEffect
的dependencies
,也就是填入的資料有被改變時,會再一次進行裡面的動作 - 若
useEffect
中有return Function
,將會在消失於DOM
/重新執行useEffect之前
執行該function
那我們可以說:
useEffect = componentDidMount + componentDidUpdate + componentWillUnmount
應該可以這樣說吧 XD
先前提到的 class-based 的寫法中,useEffect 就會拆分為三種情況,而在 functional 寫法就是一個 useEffect 就可以解決了!
useState?
那 useState 是在 class-based 哪一處對應呢?
constructor(props) {
super(props)
this.state = { date: new Date() }
}
就是這邊啦! this.state
但在 class-based 中,如果要更改狀態的話,我認為 class-based 較為方便,但還是不喜歡
假設有一組資料:
this.state = {
name: "charlie",
age: 25,
gender: "male",
}
透過 this.setState,會幫我們合併新舊資料,這一點與 Hook 的 setState 較為不同
this.setState = {
name: "john",
//就不用再把prevState寫出來再合併
}
Class-based or Functional
當然是 Functional (個人最愛?)
- 不用去想 this 的問題,也不用去想 class or inherit 的問題,看起來比較簡潔(個人覺得),而且 class 是 ES6 才有的語法糖
- 不過以 class 來說,比較複雜的資料保存、操作反而 class 的寫法就較容易方便
- 那要拋棄嗎? 由於 Hook 是近年才出現的新東西,class-based 仍然會在許多文件或是專案看見,沒有必要到拋棄,多理解也不會太困難。
08/19,以上有誤再請告知指正>_<