about 2 years ago

參考至 Function as Child Components
建立父項MyComponent

class MyComponent extends React.Component { 
  render() {
    return (
      <div>
        // 執行 children 函數 render 子項Component
        {this.props.children('Scuba Steve')}
      </div>
    );
  }
}
// 建立 props 函數
MyComponent.propTypes = {
  children: React.PropTypes.func.isRequired,
};

使用父項MyComponent

<MyComponent>
  {(name /* this.props.children('Scuba Steve') */) => (
    // 子項Component
    <div>{name}</div>
  )}
</MyComponent>

這樣的好處是可以避免 子項Component 的 props 命名衝突
因為 子項Component 可以各自針對自身的特性
對 父項Component 所傳遞的 props 參數值做選擇性接收
不一定要如同 HOC 那樣接收固定的 props 參數

轉換 HOC 至 Render prop 模式
原本的 HOC模式

const MenuHoc = (Component, functionId = 0) => class extends React.Component {
    render() {
      return (
        <Layout className="ant-layout-has-sider">
          <MenuSider functionId={functionId}/>
          <Layout>
            <MenuHeader />
            <MenuBreadcrumb functionId={functionId} />
            <Content style={{ padding: 10, background: '#fff', minHeight: window.innerHeight - 102 }}>
                  // 傳遞的子項Component
                  <Component {...this.props} />
            </Content>
          </Layout>
      </Layout>
      )
    }
}

使用 MenuHoc 方式, 這邊搭配 react-loadable 的 Loadable 做等待載入顯示

const HomeContainer = MeunHoc(
    Loadable({
        loader: () => import('./HomeContainer'),
        loading: MyLoadingComponent
    })
);

轉換為 Render prop 模式

class MenuFAC extends React.Component {
    render() {
      return (
        <Layout className="ant-layout-has-sider">
          <MenuSider functionId={this.props.functionId}/>
          <Layout>
            <MenuHeader />
            <MenuBreadcrumb functionId={this.props.functionId} />
            <Content style={{ padding: 10, background: '#fff', minHeight: window.innerHeight - 102 }}>
                // 執行 children 函數 render 子項Component
                {this.props.children(/*可自訂要傳遞給子項Component 的 props 參數*/)}
            </Content>
          </Layout>
      </Layout>
      )
    }
}

MenuFAC.propTypes = {
    children: PropTypes.func.isRequired,
};

使用 MenuFAC 方式

// 因為 Render 須為 Component 格式, 所以必須先執行 Loadable 來產生 Component
const UserManagementContainerLoader = Loadable({
    loader: () => import('./UserManagementContainer'),
    loading: MyLoadingComponent
});

const UserManagementContainer = () => {
    return <MenuFAC functionId={62} >
                {(/*接收父項傳遞過來的props變數*/) => ( 
                    <UserManagementContainerLoader /*配置所要的props值 如 title={props.title}*/ />
                )}
           </MenuFAC>
};

進階的用法可參考
I’m Breaking up with Higher Order Components.

不過這種模式還是存在一些爭議XD....

參考來源
Function as Child Components
Use a Render Prop!

← 解決 called setState() on an unmounted component 問題
 
comments powered by Disqus