Creating elements by hand
Before we learn the declarative magic of React, we do the imperative version. The browser gives you createElement to build a new node, classList to attach classes, and appendChild to insert the node into the tree. It works. It is also verbose.
function renderBooks(books) {
bookList.innerHTML = '';
books.forEach((book) => {
const card = document.createElement('div');
card.className = 'book-card';
if (book.stock === 0) {
card.classList.add('out-of-stock');
}
card.innerHTML = `
<h3>${book.title}</h3>
<p class="author">by ${book.author}</p>
<p class="price">$${book.price.toFixed(2)}</p>
<button ${book.stock === 0 ? 'disabled' : ''}>
${book.stock === 0 ? 'Sold Out' : 'Add to Cart'}
</button>
`;
bookList.appendChild(card);
});
}Build a book card node by node, attach classes, set content, append to the parent.
Read that function carefully. For one component you have to manage the container, clear previous output, loop through data, create elements, set classes conditionally, and write template strings. For ten components on a real page, this becomes thousands of lines of imperative DOM juggling. This is exactly the pain React solves. But you have to feel it first to appreciate the fix.
Yes, if you set it to untrusted input. innerHTML parses whatever string you give it as HTML, which means a malicious string like <script>...</script> could execute. For trusted template literals built from data you control, it is fine. For anything containing user input, use textContent or create elements explicitly so the browser cannot interpret the string as markup.
Quiz: Quiz
Loading practice…