2

It would be really helpful if we could compose multiple Cx components into one functional component that accepts multiple parameters as JSX attributes and can have its own nested (child) components.

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

When creating a custom Cx component, normally we need to create a class that extends some of the base components and implements certain predefined methods, which adds complexity to the process.

Here is one possible implementation of 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>;
    }
}

For the example above, LoadingOverlay had to inherit from PureContainer and implement declareData and render methods. And I would like to be able to use something simmilar to React's stateless functional components, like this:

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>;

}

Is this possible in CxJS?

4

1 回答 1

3

CxJS allows mixing React components with CxJS components, so your second example should work, except that you should use props.loading instead of data.loading. React components can be defined as functional stateless components, or as ES6 classes extending the base React.Component class (or VDOM.Component in CxJS).

CxJS recently got support for CxJS functional components, and that would probably be the best choice for this example:

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>
);
于 2017-06-30T05:52:33.650 回答