Skip to main content

Describing the UI

React applications are built from isolated pieces of UI called components. A React component is a JavaScript function that returns markup.

Creating Your First Component

React components are regular JavaScript functions, but their names must start with a capital letter or they won’t work.
function Welcome() {
  return <h1>Hello, React!</h1>;
}
1
Define the component
2
Create a JavaScript function with a capital letter name:
3
function ProfileCard() {
  // Component logic goes here
}
4
Return JSX markup
5
Return the UI elements you want to display:
6
function ProfileCard() {
  return (
    <div className="card">
      <img src="avatar.jpg" alt="Profile" />
      <h2>Jane Doe</h2>
      <p>Software Engineer</p>
    </div>
  );
}
7
Use the component
8
Import and use it like an HTML tag:
9
function App() {
  return (
    <div>
      <ProfileCard />
    </div>
  );
}

Understanding JSX

JSX is a syntax extension for JavaScript that lets you write HTML-like markup inside JavaScript files.

JSX Rules

Key differences from HTML:
  • Return a single root element (or use fragments <>...</>)
  • Close all tags (even self-closing like <img />)
  • Use camelCase for attributes (className not class, onClick not onclick)
function UserProfile() {
  return (
    <>
      <img src="photo.jpg" alt="User" className="avatar" />
      <div>
        <h1>Welcome back!</h1>
        <p>You have 3 new messages.</p>
      </div>
    </>
  );
}

Embedding JavaScript in JSX

Use curly braces {} to include JavaScript expressions:
function Greeting() {
  const name = "Alice";
  const timeOfDay = new Date().getHours() < 12 ? "morning" : "evening";
  
  return (
    <div>
      <h1>Good {timeOfDay}, {name}!</h1>
      <p>Current time: {new Date().toLocaleTimeString()}</p>
    </div>
  );
}

Nesting Components

Components can render other components to create complex UIs:
function Avatar({ src, alt }) {
  return <img src={src} alt={alt} className="avatar" />;
}

function UserInfo({ name, email }) {
  return (
    <div className="user-info">
      <h3>{name}</h3>
      <p>{email}</p>
    </div>
  );
}

function UserCard({ user }) {
  return (
    <div className="card">
      <Avatar src={user.avatar} alt={user.name} />
      <UserInfo name={user.name} email={user.email} />
    </div>
  );
}
Never define components inside other components! This causes performance issues and bugs. Always define each component at the top level.

Passing Props

Props let you pass data from parent to child components:
function Button({ text, color, icon }) {
  return (
    <button className={`btn btn-${color}`}>
      {icon && <span className="icon">{icon}</span>}
      {text}
    </button>
  );
}

function App() {
  return (
    <div>
      <Button text="Save" color="primary" icon="💾" />
      <Button text="Delete" color="danger" icon="🗑️" />
      <Button text="Cancel" color="secondary" />
    </div>
  );
}

Default Props

Provide default values using JavaScript default parameters:
function Card({ title = "Untitled", children, variant = "default" }) {
  return (
    <div className={`card card-${variant}`}>
      <h2>{title}</h2>
      <div className="card-body">{children}</div>
    </div>
  );
}

Organizing Component Files

As your app grows, organize components into separate files:
// components/Button.jsx
export default function Button({ children, onClick, variant = "primary" }) {
  return (
    <button className={`btn btn-${variant}`} onClick={onClick}>
      {children}
    </button>
  );
}

// components/Header.jsx
import Button from './Button';

export default function Header() {
  return (
    <header>
      <h1>My App</h1>
      <Button variant="secondary">Login</Button>
    </header>
  );
}

// App.jsx
import Header from './components/Header';

function App() {
  return (
    <div>
      <Header />
      {/* Rest of your app */}
    </div>
  );
}

File Naming Conventions

  • Use PascalCase for component files: UserProfile.jsx, NavBar.jsx
  • Use lowercase for utility files: utils.js, helpers.js
  • Keep one component per file (with exceptions for small related components)

Complete Example

Here’s a complete example bringing everything together:
// components/ProductCard.jsx
function ProductImage({ src, alt }) {
  return (
    <div className="product-image">
      <img src={src} alt={alt} />
    </div>
  );
}

function ProductInfo({ name, price, inStock }) {
  return (
    <div className="product-info">
      <h3>{name}</h3>
      <p className="price">${price.toFixed(2)}</p>
      {!inStock && <span className="badge">Out of Stock</span>}
    </div>
  );
}

export default function ProductCard({ product }) {
  return (
    <article className="product-card">
      <ProductImage src={product.image} alt={product.name} />
      <ProductInfo 
        name={product.name}
        price={product.price}
        inStock={product.inStock}
      />
      <button disabled={!product.inStock}>
        {product.inStock ? "Add to Cart" : "Notify Me"}
      </button>
    </article>
  );
}

// App.jsx
import ProductCard from './components/ProductCard';

function App() {
  const products = [
    { id: 1, name: "Laptop", price: 999.99, image: "/laptop.jpg", inStock: true },
    { id: 2, name: "Mouse", price: 29.99, image: "/mouse.jpg", inStock: false },
  ];

  return (
    <div className="product-grid">
      {products.map(product => (
        <ProductCard key={product.id} product={product} />
      ))}
    </div>
  );
}

Next Steps

Now that you understand components and JSX, learn how to make your components interactive with event handlers.