AEM 6560 - SPA Editor Container Class as React SPA Functional Component

Goal

React hooks are not allowed in class components. This post is for using hooks in AEM Editable Component Container coded as a Class. In the following example we use Material UI useMediaQuery hook in a AEM SPA Editable Component for setting breakpoint specific background height...


Container on Desktop


Container on Mobile



Component TypeScript


import React, { FC, useState, useEffect, Component, ComponentType } from "react";
import CSS from 'csstype';
import { MapTo, Container } from "@adobe/cq-react-editable-components";
import useMediaQuery from '@material-ui/core/useMediaQuery';
import { useTheme, createMuiTheme } from '@material-ui/core/styles';

enum BREAKPOINT {
    XS = 0,
    SM = 768,
    MD = 992,
    LG = 1200,
    XL = 1600
}

const eaemTheme = createMuiTheme({
    breakpoints: {
        values: {
            xs: BREAKPOINT.XS,
            sm: BREAKPOINT.SM,
            md: BREAKPOINT.MD,
            lg: BREAKPOINT.LG,
            xl: BREAKPOINT.XL
        }
    }
});

interface EAEMContainerPropTypes {
    containerProps: any,
    childComponents: any,
    placeholderComponent: any
}

const EAEMContainerWrapper = (Component: React.FC<any>) => class EAEMContainer extends Container<any, any> {
    props: any

    constructor(props: any) {
        super(props);
        this.props = props;
    }

    render() {
        return (
            <Component {...Object.assign({}, this.props, {
                containerProps: super.containerProps,
                childComponents: super.childComponents,
                placeholderComponent: super.placeholderComponent
            })}>
            </Component>
        );
    }
}

const EAEMPositioningContainer: FC<EAEMContainerPropTypes> = ({ containerProps, childComponents, placeholderComponent, ...props }) => {
    let height = "500px";

    //cannot use conditional if-else statements with React hooks
    let matches = useMediaQuery(eaemTheme.breakpoints.down('md'));

    if (matches) {
        height = "300px";
    }

    matches = useMediaQuery(eaemTheme.breakpoints.down('sm'));

    if (matches) {
        height = "100px";
    }

    containerProps.style = {
        height: height,
        "background-color" : "yellow"
    }

    return (
        <div {...containerProps}>
            {childComponents}
            {placeholderComponent}
        </div>
    );
};

export default MapTo("eaem-sites-spa-how-to-react/components/positioning-container")(
    EAEMContainerWrapper(EAEMPositioningContainer)
);



No comments:

Post a Comment