This episode teaches conditional rendering with ternary and logical operators, then rendering lists with stable keys. You'll also learn about Fragments, portals, and error boundaries, plus best practices for building truly dynamic UI.

Real apps rarely display the same thing over and over. Sometimes you show a loading spinner, sometimes a list of items, sometimes an empty message. Sometimes you need to render dozens of items from an array. Those are the two skills episode 7 covers: conditional rendering and rendering lists.
We'll also look at Fragments to group elements without extra tags, portals to render outside the DOM hierarchy, and error boundaries so a single error doesn't bring down the entire app. These are important parts of dynamic UI that feels professional.
The ternary expression is best suited for choosing between two views:
function Status({ masuk }) {
return (
<div>
{masuk ? <p>Selamat datang kembali</p> : <button>Login</button>}
</div>
)
}{masuk ? <p>...</p> : <button>...</button>} renders the paragraph if masuk is true, and the button if false. Ternary expressions can be nested, but it's better to split them into small components if they start getting deeply nested.
To display something only when the condition is true (without an else branch), use &&:
function Notifikasi({ pesan }) {
return (
<div>
{pesan.length > 0 && <p className="notice">{pesan}</p>}
</div>
)
}{pesan.length > 0 && <p>...{:javascript}</p>} renders the element only if the left-hand expression is truthy. Be careful with numbers: {jumlah && <p>...}</p> will render 0 if jumlah is zero — use an explicit condition like jumlah > 0.
The way to render an array is with map, which returns JSX elements:
function DaftarProduk({ produkList }) {
return (
<ul>
{produkList.map((produk) => (
<li key={produk.id}>{produk.nama} - Rp{produk.harga}</li>
))}
</ul>
)
}produkList.map((produk) => <li key={produk.id}>...{:javascript}</li>) turns each array item into a list element. Notice the key prop, which is required for each item.
key helps React identify which items changed, were added, or were removed. The rules:
Using the index as a key causes bugs when items are inserted or removed in the middle of a list — an item's state can end up connected to the wrong item.
Sometimes you need several elements at once without wrapping them in a div. Fragments solve this:
function Detail() {
return (
<>
<h2>Judul</h2>
<p>Paragraf pertama</p>
<p>Paragraf kedua</p>
</>
)
}<>...</> is the shorthand syntax for React.Fragment. Useful when filling CSS grids or tables that can't have an extra wrapper element.
A portal renders children into a different DOM node than their parent. Modals, tooltips, and dropdowns are the best fit for this:
import { createPortal } from "react-dom"
function Modal({ anak }) {
return createPortal(
<div className="overlay">{anak}</div>,
document.getElementById("modal-root")
)
}createPortal(jsx, document.getElementById("modal-root")) renders the content into a modal-root element separate from #root. Add <div id="modal-root"></div> to index.html so the target element always exists.
Error boundaries catch render errors in child components so they don't wipe out the entire app. Since there's no hook for this yet, they have to be class components:
class ErrorBoundary extends React.Component {
state = { error: null }
static getDerivedStateFromError(error) {
return { error }
}
render() {
if (this.state.error) {
return <p>Terjadi kesalahan: {this.state.error.message}</p>
}
return this.props.children
}
}static getDerivedStateFromError(error) stores the error in state, then render shows a fallback UI instead of a blank page. Wrap error-prone areas with <ErrorBoundary>...</ErrorBoundary>.
A few habits that keep dynamic UI healthy:
npm run devTry rendering DaftarProduk with produkList=[] — the empty list shows nothing. Add a condition like {produkList.length === 0 && <p>Belum ada produk</p>} for a better experience.
Episode 7 completed the dynamic UI foundation: conditional rendering with ternary and &&, rendering lists with stable keys, Fragments, portals for modals, and error boundaries so one error doesn't collapse the app.
Key takeaways:
&& for showing or hiding.map renders lists; always include a stable, unique key.<>...</> group elements without an extra DOM node.In the next episode, episode 8, we'll cover data fetching & asynchronous UI — fetching data with fetch, axios, and async/await, managing loading and error states, stable Suspense patterns, and caching with React Query or SWR. Your app starts communicating with the real world.