This episode teaches you how to write function components and JSX syntax complete with JavaScript expressions inside. You'll also learn three styling approaches: plain CSS, CSS Modules, and styled-components, plus composition patterns using props and children.

Here's the moment you've been waiting for: writing real components and JSX. JSX is the language you'll use every day — a mix of HTML and JavaScript that makes UI structure easy to read and annotate with logic.
Episode 4 covers function components, JSX syntax rules, how to embed JavaScript expressions, and then the three styling approaches most commonly used in the React ecosystem: plain CSS, CSS Modules, and styled-components. Finally, you'll learn composition — how to assemble small components into a large interface.
A function component is simply a JavaScript function that returns JSX. The convention: the name starts with a capital letter so React recognizes it as a component, not an HTML element:
function Avatar({ nama, peran }) {
return (
<figure>
<img src="/avatar-default.png" alt={nama} />
<figcaption>{nama} - {peran}</figcaption>
</figure>
)
}The Avatar component receives the nama and peran props and renders them inside JSX. src="/avatar-default.png" is a regular attribute, while alt={nama} is a JavaScript expression — the difference lies in the curly braces.
Here are some important rules to remember:
div or a fragment <>...</>.className, not class.{ expression }.<img />.const nama = "Dunia"
function Ucapan() {
return (
<>
<h1 className="judul">Halo, {nama.toUpperCase()}</h1>
<input placeholder="Ketik sesuatu" />
</>
)
}{nama.toUpperCase()} calls a JavaScript method inside JSX — anything that evaluates to a value can go there, including function calls and ternary expressions.
Comments inside JSX are written with {/* comment content */} because // would be treated as an expression. For conditions, a ternary expression is preferred over an if statement because if can't be placed directly inside JSX.
The simplest approach: import a CSS file and use className. This style is easy to get started with but risks class name collisions in large projects.
import "./avatar.css"
function Avatar() {
return <img className="avatar" src="/avatar-default.png" alt="avatar" />
}CSS Modules turn class names into unique values at build time, so they never collide. Files are given the .module.css suffix:
import styles from "./avatar.module.css"
function Avatar() {
return <img className={styles.avatar} src="/avatar-default.png" alt="avatar" />
}import styles from "./avatar.module.css" creates a styles object containing the unique class names from the build. This style is the default for many production projects because its scoping is safe.
styled-components writes CSS directly inside your JavaScript component using template literals. Install it first:
npm install styled-componentsimport styled from "styled-components"
const Tombol = styled.button`
background: #2563eb;
color: white;
padding: 8px 16px;
border-radius: 6px;
`
function App() {
return <Tombol>Kirim</Tombol>
}styled.button creates a button element with CSS styling, then reuses it as the Tombol component. This approach keeps style and logic in one place, and is popular for design systems.
children is a special prop that contains the content between a component's opening and closing tags. It's the foundation of composition:
function Kotak({ judul, children }) {
return (
<section>
<h2>{judul}</h2>
<div>{children}</div>
</section>
)
}
function App() {
return (
<Kotak judul="Pengaturan">
<label>Nama: <input /></label>
</Kotak>
)
}{children} renders whatever is placed between <Kotak>...</Kotak>. This pattern lets a component be used to build layouts: Kotak is written once, and its contents can differ every time it's used.
React doesn't recommend inheritance between components. Instead, use composition: small components are given specific responsibilities, then assembled together. Large UIs are built from small pieces that can be tested and reused independently.
Episode 4 made you productive with React: writing function components, understanding JSX rules, embedding JavaScript expressions, choosing between three styling approaches, and assembling UI with the composition and children patterns.
Key takeaways:
className and { ... } expressions; every tag must be closed.children is a special prop for the content between a component's tags.In the next episode, episode 5, we'll cover state & event handling — useState for local state, the synthetic event system, controlled components for forms, and batching and re-render behavior. This is where your app really starts to become interactive.