iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 13
0
自我挑戰組

React初心者30天的探索之路系列 第 13

[Day 13] React Higher-Order Components (HOC)

  • 分享至 

  • xImage
  •  

想必我們都曾經遇過一種情境,兩個component功能幾乎一模一樣,只是差在輸入的資料不同而已,那麼這時候就是HOC登場的時候了,HOC為一個可以傳入component當參數的function,其目的在於可以將重複的邏輯抽離出來,讓傳入的component可以套用這個邏輯,並且輸出一個全新的component

當初看到redux的connect還想說這是什麼神秘的寫法,原來就是HOC啊!

const Counter = connect(
   mapStateToProps,
   mapDispatchToProps
)(Counters);

被作為參數的component稱之為Wrapped Component

以下就來實做一下HOC,這是HOC component,實現一個簡單的時鐘功能

可以看到HOC component接收到一個component之後,將計算後的結果(每秒更新當前時間)透過props傳遞到 wrapped component裡面

function WithTime(InnerComponent) {
    class OuterComponent extends Component{
        state = {
            time: new Date().toLocaleTimeString()
        }
        componentDidMount(){
            this.interval = setInterval(() => {
                this.setState({
                    time: new Date().toLocaleTimeString()
                }) 
            }, 1000);
        }
        componentWillMount(){
            clearInterval(this.interval)
        }
        render(){
            return <InnerComponent time={this.state.time} />
        }
    }
    return OuterComponent
}

這是要被傳入的component(僅負責ui,沒有邏輯處理),透過props取得hoc component輸入的資料,可以看到最後export 出去的是withTime回傳的新component

import React, { Component } from 'react'
import WithTime from './WithTime'

class HocExample extends Component{
    render(){
        return (<h1>{this.props.time}</h1>)
    }
}

export default WithTime(HocExample) 

恩…又報錯了

字面上好像是我傳入了不合法的格式?一開始以為是不能傳時間物件?搞了老半天才發現,其實問題是在render的地方直接渲染物件, 將state轉換一下格式換成時間字串就可以了。

toLocaleTimeString() 可以直接轉成當地時間字串

在估狗資料的時候一直看到HOC波動拳(HOC wrapper hell),想說那是啥,看到下面那張圖就瞬間明白了什麼,因為HOC包HOC,層層嵌套之下就會衍生這個問題,後面會再介紹React Hook如何解決這個問題。

圖片來源:推特作者@GrexQL


上一篇
[Day 12] React event - 事件處理
下一篇
[Day 14] 用React Ref 來操作DOM
系列文
React初心者30天的探索之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言