組件複用方式 | 優點 | 劣勢 | 狀態 |
---|---|---|---|
類組件(class) | 發展時間長,接受度普遍 | 只能繼承父類 | 傳統模式,長期存在 |
Mixin | 能夠複製任意對象的任意多個方法 | 組件相互依賴、耦合,可能產生衝突,不利於維護 | 被拋棄 |
高階組件(HOC) | 利用裝飾器模式,在不改變組件的基礎上,動態地爲其添加新的能力 | 嵌套過多調試困難,須要遵照某些約定(不改變原始組件,透傳props等) | 能力強大,應用普遍 |
Hooks | 代替class,多個Hooks互不影響,避免嵌套地獄,開發效率高 | 切換到新思惟須要成本 | React將來 |
高階組件
- 總結高階組件用在TS中:
- 首先會遇到比較多的類型問題,解決這些問題一般不會很順利,並且會存在一些隱性的bug,這並非HOC自己的問題,而是react的聲明文件尚未很好的支持HOC的類型檢查
import React, { Component } from "react"; import HelloClass from './HelloClass'; interface Loading { loading: boolean; } function HelloHOC<P>(WrappedComponent: React.ComponentType<P>) { return class extends Component<P & Loading> { // 交叉類型,讓被包裝的組件同時具備loading類型 render() { const { loading, ...props } = this.props; return loading ? <div>Loading...</div> : <WrappedComponent {...props as P} /> } } } export default HelloHOC(HelloClass);
更推薦Hooks編寫組件react
Hooks
import React, { useEffect, useState } from 'react'; import { Button } from 'antd'; interface Greeting { name: string; firstName: string; lastName: string; } const HelloHooks = (props: Greeting) => { const [count, setCount] = useState(0); const [text, setText] = useState<string | null>(null); useEffect(() => { if (count > 5) { setText('休息一下'); } }, [count]); return ( <> <p>你點擊了 {count} 下 {text}</p> <Button onClick={() => {setCount(count + 1)}}>Hello {props.name}</Button> </> ); }; HelloHooks.defaultProps = { firstName: 'first', lastName: 'last', }; export default HelloHooks;