iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0
自我挑戰組

React 學習之路系列 第 21

第一個 HOC (Higher-Order Components)( Day21 )

  • 分享至 

  • xImage
  •  

A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature. - React Document

higher-order component 是一個函式,輸入一個 component 並回傳一個 component。

我的第一個 HOC

const myFirstHoc = (Component, handler) => {
   return (props) =>
    <Component
      {...props}
      onClick={(event) => handler.click(event)}
    />
}

Codepen 完整程式

HOC 的幾種形式

單一參數

const NavbarWithRouter = withRouter(Navbar);

兩個參數,Component + 設定

const CommentWithRelay = Relay.createContainer(Comment, config);

HOC 回傳 HOC

// React Redux's `connect`
const ConnectedComment = connect(commentSelector, commentActions)(CommentList);

//同等於
// connect is a function that returns another function
const enhance = connect(commentListSelector, commentListActions);
// The returned function is a HOC, which returns a component that is connected
// to the Redux store
const ConnectedComment = enhance(CommentList);

HOC 注意事項

不要在 render 方法中使用 HOC

render() {
  // A new version of EnhancedComponent is created on every render
  // EnhancedComponent1 !== EnhancedComponent2
  const EnhancedComponent = enhance(MyComponent);
  // That causes the entire subtree to unmount/remount each time!
  return <EnhancedComponent />;
}

將 React component 的靜態方法複製過來

function enhance(WrappedComponent) {
  class Enhance extends React.Component {/*...*/}
  // Must know exactly which method(s) to copy :(
  Enhance.staticMethod = WrappedComponent.staticMethod;
  return Enhance;
}

HOC 會通過所有的 props, 但 Refs 不會

初步學習覺得 HOC 很抽象,而 HOC 有很多不同的形式跟工具,例如複製靜態方法會用 hoist-non-react-statics 套件,第三方實作向 Redux 的 connect 和 Relay 的 createFragmentContainer 等,值得後續深入研究。

以上今天。

參考資料:
https://zh-hant.reactjs.org/docs/higher-order-components.html


上一篇
Render Props ( Day20 )
下一篇
[進階指南] 錯誤邊界 ( Day22 )
系列文
React 學習之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言