如何在 CxJS 中制作功能组件?

How to make functional components in CxJS?

如果我们可以将多个 Cx 组件组合成一个功能组件,该组件接受多个参数作为 JSX 属性并且可以有自己的嵌套(子)组件,那将非常有帮助。

<LoadingOverlay loading={bind('$page.loading')} >
    <Grid />
</LoadingOverlay/>

在创建自定义 Cx 组件时,通常我们需要创建一个 class 来扩展一些基础组件并实现某些预定义的方法,这增加了过程的复杂性。

这是 LoadingOverlay 的一种可能实现:

class LoadingOverlay extends PureContainer {

    declareData() {
        super.declareData(...arguments, {
            loading: undefined
        });
    }

    render (context, instance, key) {
        let {data} = instance;
        return <div key={key} className="cxb-loading-overlay-container">
            {this.renderChildren(context, instance)}
            {data.loading && <div className="cxe-loading-overlay">
                <div className="cxe-loading-indicator">
                    {Icon.render('loading', { 
                            style: {
                                width: '24px', 
                                height: '24px',
                                position: 'relative',
                                top: '6px' 
                            } 
                        })
                    } 
                    Loading...
                </div>
            </div>}
        </div>;
    }
}

对于上面的示例,LoadingOverlay 必须继承自 PureContainer 并实现 declareDatarender 方法。 我希望能够使用类似于 React 的无状态功能组件的东西,像这样:

const LoadingOverlay = (props) => {

    return <div className="cxb-loading-overlay-container">
        {props.children}
        {data.loading && <div className="cxe-loading-overlay">
            <div className="cxe-loading-indicator">
                {Icon.render('loading', { 
                        style: {
                            width: '24px', 
                            height: '24px',
                            position: 'relative',
                            top: '6px' 
                        } 
                    })
                } 
                Loading...
            </div>
        </div>}
    </div>;

}

这在 CxJS 中可行吗?

CxJS 允许将 React 组件与 CxJS 组件混合使用,因此您的第二个示例应该可以工作,除了您应该使用 props.loading 而不是 data.loading。 React 组件可以定义为功能性无状态组件,或者作为扩展基础 React.Component class(或 CxJS 中的 VDOM.Component)的 ES6 classes。

CxJS 最近获得了对 CxJS functional components 的支持,这可能是这个例子的最佳选择:

const LoadingOverlay = ({ loading, children }) => (
  <cx>
    <div className="cxb-loading-overlay-container">
      {children}
      <div className="cxe-loading-overlay" visible={loading}>
        <div className="cxe-loading-indicator" ws>
          <Icon
            name="loading"
            style="width:24px;height:24px;position:relative;top:6px"                        
          />
          Loading...
        </div>
      </div>
    </div>;
  </cx>
);