I'm using Preact with HTM (no compiler required) and am having trouble looping through an object and creating a DOM element for each item.
What is the correct way to procedurally generate DOM elements with Preact + HTM?
import { h, Component, render } from 'https://unpkg.com/preact?module';
import htm from 'https://unpkg.com/htm?module';
const html = htm.bind(h);
function componentValues() {
var elements = {e1:10, e2:20};
var objEditor = '<div class="row">';
for (const key in elements) {
objEditor += '<div class="col">'+key+'</div>';
}
objEditor += '</div>';
return objEditor;
}
function renderPage() {
render(html`
<div class="container-xl">
<p>Hello World</p>
<${componentValues} />
</div>`, document.getElementById("app"));
}
renderPage();
My result is this
Hello World
<div class="row"><div class="col">e1</div><div class="col">e2</div></div>
https://codepen.io/28raining/pen/WNyaJrL
Are you looking to use HTML strings in JSX or simply find the most idiomatic way to go about generating new entries?
If this is the latter (as your description seems to indicate), you definitely want to avoid using strings. You have JSX at your disposal; use it to template out your content rather than string concatenation.
Try this:
function componentValues() {
var elements = {e1:10, e2:20};
return html`
<div class="row">
${Object.entries(elements).map(([key, value]) =>
html`<div class="col">${key}</div>`
)}
</div>
`;
}
If you did need to use HTML strings (it happens, though should be avoided if at all possible), that string isn't a JSX element/component, so you can't use it as one. Instead, you need to wrap it with html:
function renderPage() {
render(html`
<div class="container-xl">
<p>Hello World</p>
${html([componentValues()])}
</div>`,
document.getElementById("app")
);
}
Tagged template functions (html in this case) get arguments as arrays, hence why we create a new array and add the result of componentValues() to it.
As rschristian proposed, the solution is with arrays. rschristian's solution is limited by what you're allowed to put in a template string.
function compRow() {
return html`<div class="row">${componentValues()}</div>`
}
//Boxes for users to add components
function componentValues() {
var elements = state.elements;
var objEditor = []
for (const key in elements) {
objEditor.push(html`<div class="col">${key}</div>`);
}
return objEditor;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With