Как сделать функциональные компоненты в CxJS?

Было бы очень полезно, если бы мы могли объединить несколько компонентов Cx в один функциональный компонент, который принимает несколько параметров в качестве атрибутов JSX и может иметь свои собственные вложенные (дочерние) компоненты.

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

При создании пользовательского компонента Cx обычно нам необходимо создать класс, который расширяет некоторые базовые компоненты и реализует определенные предопределенные методы, что добавляет сложности процессу.

Вот одна из возможных реализаций 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 и реализовать declareData а также render методы. И я хотел бы иметь возможность использовать что-то похожее на функциональные компоненты 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?

1 ответ

Решение

CxJS позволяет смешивать компоненты React с компонентами CxJS, поэтому ваш второй пример должен работать, за исключением того, что вы должны использовать props.loading вместо data.loading, Компоненты React могут быть определены как функциональные компоненты без состояний или как классы ES6, расширяющие базовый класс React.Component (или VDOM.Component в CxJS).

CxJS недавно получил поддержку функциональных компонентов CxJS, и это, вероятно, будет лучшим выбором для этого примера:

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>
);
Другие вопросы по тегам