Blogs > Mapping AEM Component to React Component
AEM SPA
Mapping AEM Component to React Component
| April 11, 2023The Basic concept is to map the AEM component to React component, Basically AEM Component runs at Server side and it exports the content in the form of JSON Model API.so that JSON file - for e.g (en.model.json) is consumed by our React Component running at an Client side in the browser. We'll know more about the following concept with the help of the following diagram.
Steps to map AEM component to React component :
Create an AEM component by right clicking on components folder under wknd-spa-react project -> create component. Add label, title and component group to the component and create it.
Let's consider, 'test' is our component in wknd-spa-react project and its path will be wknd-spa-react/components/test. Create the dialog box through which author can author the fields.
Create a sling model so that you can map the authored values with backend. Add adaptables, adapters & resourceType to the @Model annotation. Inherit the ComponentExporter interface to the serviceImpl class, and we need to override the getExporterType() method which will return the resourceType of the component.
It is mandatory to implement ComponentExporter as it is used to export the content of our component in JSON format.
On hitting test.model.json you will find the response in json format.
In ui.frontend folder/src right click on components folder and create Test.js file. Import the React and MapTo from 'react' and @adobe/aem-react-editable-components libraries.
Create a class component & write a JSX script in render() method, at last add MapTo() function and export the class e.g MapTo("wknd-spa-react/components/test")(Test, TestEditConfig);
With MapTo() you can map your React component to Sling Model using the resourceType
Import your React component in import-component.js file and similarly import your import-component.js file in index.js
MapTo() will look for sling model registered with the same resource type that we have passed in MapTo().
Build ui.frontend folder with $ mvn clean install -PautoInstallPackage Search for your component, you will find minified form of js in ui.apps folder.
Deploy the SPA code to AEM using Maven
$ mvn clean install -PautoInstallSinglePackage.Open AEM, On Navigation select Sites, click on create button and select Page, Choose the template, add title to the page and click on Done.
Add Component 'test', author it and you will find the data rendered on your page.
Click On Preview, inspect your page, In Network tab you will find 'en.model.json' .The Layout Container has a sling:resourceType of your component and is recognized by the SPA Editor using the :type property, just like the Text and Image components.
package com.adobe.aem.guides.wknd.spa.react.core.models.impl;
import com.adobe.aem.guides.wknd.spa.react.core.models.Test;
import com.adobe.aem.guides.wknd.spa.react.core.pojos.NavigationBarPojo;
import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.ExporterConstants;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
@Model(adaptables = SlingHttpServletRequest.class,
adapters = {Test.class,ComponentExporter.class},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL,
resourceType = TestModelImpl.RESOURCE_TYPE)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class TestModelImpl implements Test {
static final String RESOURCE_TYPE = "wknd-spa-react/components/test";
@ValueMapValue
private String name;
@Override
public String getName() {
return name;
}
@Override
public String getExportedType() {
return TestModelImpl.RESOURCE_TYPE;
}
}
import React, { Component } from "react";
import { useState } from 'react';
import { MapTo } from "@adobe/aem-react-editable-components";
export const TestEditConfig = {
emptyLabel: "Test",s
isEmpty: function (props) {
return !props || !props.name ;
},
};
export default class Test extends Component {
render() {
if (TestEditConfig.isEmpty(this.props)) {
return null;
}
return (
<p>className="TestComponents">
{this.props.name}
</p>
);
}
}
MapTo("wknd-spa-react/components/test")(Test,TestEditConfig);