Reputation: 35
Running into an issue rendering components dynamically as the come off the CMS in the react code.
Having no problem getting & parsing the variable names into an array to be utilized in the actual rendering - but receiving errors here no matter the method I'm using:
Which clearly shows I'm using caps :)
import React, {
Component
} from 'react';
import {
createClient
} from 'contentful';
import CtaBlock from './CTABlock';
import DeviceList from './DeviceList';
class HomeContainer extends Component {
constructor(props) {
super(props);
this.state = {
pageCont: [],
entries: []
};
}
componentDidMount() {
const client = createClient({
// This is the space ID. A space is like a project folder in Contentful terms
space: '...',
// This is the access token for this space. Normally you get both ID and the token in the Contentful web app
accessToken: '...'
});
client.getEntries({
'sys.id': '5stYSyaM8gkiq0iOmsOyKQ'
}).then(response => {
this.setState({
mainCont: response
});
});
}
getEntries = pageCont => {
var linkedEntries = pageCont.includes.Entry;
console.log(linkedEntries);
return linkedEntries;
};
render() {
var formattedComponents = [];
var renderedComponents = [];
if (this.state.mainCont) {
//getting the type of component from the Contetful API (String)
var componentList = this.getEntries(this.state.mainCont).map(entries => entries.sys.contentType.sys.id);
//converting the component names to upper case
formattedComponents = componentList.map(comps => comps.charAt(0).toUpperCase() + comps.slice(1));
renderedComponents = formattedComponents.map(MyComponent => {
return <MyComponent / >
});
}
return (
<div>
<h1> Dynamically Generated Components Div </h1>
{renderedComponents}
</div>
);
}
}
export default HomeContainer;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Appreciate any insight!
Upvotes: 2
Views: 4061
Reputation: 623
When I understand you right, what you want to archive is, to map a string key to a certain component, right?
So that entries.sys.contentType.sys.id
contains a string like "ctaBlock"
or "deviceList"
?
I would suggest using a map as follows:
import CtaBlock from './CTABlock';
import DeviceList from './DeviceList';
import FallbackComponent from './FallbackComponent';
const keyMap = {
ctaBlock : CtaBlock,
deviceList : DeviceList,
default: FallbackComponent,
};
...
componentList.map( entries => {
const key = entries.sys.contentType.sys.id;
const Component = keyMap[ key ] || keyMap.default;
return <Component />;
} );
See an example on: https://jsfiddle.net/v7do62hL/2/
Upvotes: 2