面試考題 2024 - HOC是什麼(實作) ===  --- ###### tags: `面試問題`, `練習問題`, `2024` HOC 完整名稱是 Higher-Order Component ,簡單地解釋是一種基於React的組合特性而形成的設計模式。 沒錯!我認為每一位 JR 都必須修練的技術,通常都會看到 SR 或者 TechLead 說要製作更加彈性的 Component 供多個網頁使用,一來容易整合,一來是減少多餘的重複性作業。 比較官方的寫法: **HOC是一個函數(function)**,它接受一個組件作為參數,並返回一個新的組件。(簡單說就是給一個jsx.element 放進這個function 然後強化以後,成為一個全新的 jsx.element)。 **它不是組件本身**,而是一個創建組件的函數。 HOC 的目的是重用組件邏輯,特別是那些在**多個組件中共享的邏輯**。  ### HOC的用法: * **增強組件的功能**: 可以為組件添加額外的屬性或邏輯 * **條件渲染**: 根據某些條件改變組件的行為或樣式 * **訪問控制**: 例如,限制某些組件的訪問。 * **狀態管理與數據綁定**: 例如,連接到Redux 或 Context API。 ## HOC實作示範: ```jsx! // 這是一個簡單的組件 // 然後要從localStorage 拿到data裡的name // 放入這個component裡。 const SimpleComponent = props => <div>Hello {props.name}!</div> function withStorage(component){ return function EnhancedComponent(props) { const savedData = localStorage.getItem('data'); return <Component {...props} data={savedData} /> } } const SimpleComponentWithStorage = withStorage(SimpleComponent); function App(){ return <SimpleComponentWithStorage name="Gordon" /> } ``` ### 解說: * HOC的原理設計是 withStorage 必須是返回成一個新的Component。 * HOC設計是為了達到封裝可復用的邏輯或行為精神。 * 跟性能問題無關,而是為了保持HOC的正確抽象,靈活性和可復永用性而設計。 ### 過程分解: 1. 獲取數據: * 在**EnhancedComponent**的函數體內,**localStorage.getItem('data')** 被調用來獲取存儲在本地存儲中的數據。這個 **data** 被視為一個要添加到組件中的新屬性。 2. 傳遞原始 props: * 使用 **{...props}** 這種展開操作符的方式,可以確保所有傳遞給**EnhancedComponent的 props (例如 name)** 都會被原樣傳遞給內部的 Component。 這確保了增強組件的行為與原始組件盡**可能保持一致,同時增加了額外的功能或數據**。 3. 添加新屬性: * **data={savedData}** 這一行代碼將從 **localStorage 獲取的數據作為 data** 屬性傳遞給 Component。這樣,增強後的組件除了原始的 props 外,還能**接收到新的 data 屬性**。 ### 這裡的總結: 其實HOC是在一個完成的功能,可能是JSX.element 完成了設計,後來被要求要額外接一個功能啦,可能要新增某些呈現啦,那就很適合用 HOC 來規劃下和再不需要太大動到原始程式。 ## 進入進階版! ```jsx! //權限驗證 HOC function withAuthorization(Component){ return function WrappedComponent(props){ if(!props.user.hasPermission){ return <div>No access</div>; } return <Component {...props} /> }; } //數據獲取 HOC function withUserData(Component){ return function WrappedComponent(props){ const [userData, setUserData] = useState(null); useEffect(()=>{ fetchUserData(props.userId).then(data=> setUserData(data)); },[props.userId]); if(!userData){ return <div>Loading ...</div> } return <Component {...props} userData={userData}/> }; } const EnhancedUserProfile = withUserData(withAuthorization(UserProfile)); ``` * 使用HOC的關鍵 是它允許你保持組件的關注點分離和單一職責原則。 * 它使得組件保持見解,而功能性的增加則通過外部封裝實現。 * 這樣即使需求變動頻繁,也能靈活應對,而不會影響到組件的核心邏輯。 * 這種模式提高了代碼的可維護性,可擴展性和再利用性。 --- ## 總結 當你通過HOC為組件添加新的props 或 狀態時,組件應該能夠使用這些新增的 props 來更新其 UI。 確保組件能夠響應這些props的比拿話是使用HOC時的一個重要考慮。我覺得最直觀的做法可以理解為你有一組起始的fetching然後要整合以後再去做rendering UI的部分,那個fetching就可以分離到HOC完成,然後UI 就單純做 UI。可是這裡有個新手的大忌就是記得props不要傳超過第二層,這樣會造成 hydration 的問題喔。 當你的HOC寫的很細的話,如果遇到page UI需要用到相同的對象就可以用套的方式套起來! 希望我分享的這篇能幫助你去理解更好的寫法,當然學會了HOC並且運用在專案上或者 side,都可以在面試上炫起來喔!我們下篇再見! 
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up