React Fundamentals & Your First Component

When I started building the frontend for my multi-tenant POS system, I needed to display hundreds of products across different restaurant menus and retail catalogs. Each product needed to show its name, price, available stock, and categoryβ€”all in a consistent, reusable way. This is where I learned that React's component model isn't just a nice-to-have; it's essential for building maintainable applications.

Instead of copying and pasting HTML for each product, I built a single ProductCard component that could be reused everywhere. This one decision saved me countless hours and made the entire application easier to maintain.

What Are Components?

Components are the building blocks of React applications. Think of them as custom HTML elements that you define yourself. Just like you use <button> or <input> in HTML, in React you create components like <ProductCard> or <ShoppingCart>.

In the POS system, every piece of the UI is a component:

  • The product card displaying item details

  • The search bar filtering products

  • The navigation menu

  • The shopping cart

  • Even the entire page is a component

Your First Component: The Product Card

Let's build the most fundamental piece of the POS systemβ€”a component that displays a single product.

Step 1: A Static Component

Here's the simplest version, with hardcoded data:

// ProductCard.tsx
import React from 'react';

function ProductCard() {
  return (
    <div className="product-card">
      <h3>Mohinga</h3>
      <p className="price">3500 MMK</p>
      <p className="stock">In Stock: 24</p>
      <p className="category">Breakfast</p>
    </div>
  );
}

export default ProductCard;

What's happening here?

  1. Import React: We need React to use JSX (more on that in a moment)

  2. Define a function: Components are just JavaScript functions

  3. Return JSX: This HTML-like syntax is JSX (JavaScript XML)

  4. Export the component: So we can use it elsewhere

Using the component:

Just like that, <ProductCard /> renders our product. But there's a problemβ€”every card shows the same hardcoded data.

Understanding JSX

JSX looks like HTML, but it's actually JavaScript. When you write:

React transforms it into:

Key differences from HTML:

  1. className instead of class: Because class is a reserved word in JavaScript

  2. Self-closing tags need /: <ProductCard /> not <ProductCard>

  3. JavaScript expressions in {}: You can embed any JavaScript expression

Anything inside {} is evaluated as JavaScript. You can use variables, call functions, perform calculationsβ€”anything that returns a value.

Props: Making Components Reusable

The magic of components is props (short for properties). Props let you pass data into components, making them reusable with different data.

Step 2: Component with Props

What changed?

  1. Interface ProductCardProps: TypeScript interface defining the shape of our props

  2. Function parameter props: The component receives props as an argument

  3. Access props with dot notation: props.name, props.price, etc.

Using the component with different data:

Now we have three different products using the same component! This is the power of propsβ€”write once, reuse everywhere.

Destructuring Props (Cleaner Syntax)

Instead of writing props.name, props.price repeatedly, most React developers destructure props:

This is cleaner and more common in real codebases. The curly braces in the function parameter destructure the props object.

Conditional Rendering

In the POS system, out-of-stock items need special treatment. Let's add conditional rendering:

Conditional rendering techniques:

  1. Ternary operator: condition ? <ComponentA /> : <ComponentB />

  2. Logical AND: condition && <Component /> (renders component only if condition is true)

  3. Template literals for classes: `product-card ${isOutOfStock ? 'out-of-stock' : ''}`

Component Composition

Components can contain other components. Let's build a ProductGrid that contains multiple ProductCard components:

This creates a hierarchy:

This is component compositionβ€”building complex UIs by composing simple components together.

Adding Styles

React components can be styled in several ways. Here's how I styled the ProductCard in the POS system:

CSS Modules automatically scope styles to the component, preventing style conflicts.

The Complete Picture: Types and Real Data

In the POS system, product data comes from the Inventory Service API. Here's how we'd type that properly:

Key improvements:

  1. Structured data: Using a Product interface

  2. Optional properties: imageUrl? means it might not exist

  3. Number formatting: .toLocaleString() formats large numbers with commas

  4. Conditional image: Only render <img> if imageUrl exists

Key Learnings

After building hundreds of components in the POS system, here's what matters most:

βœ… Components Are Just Functions

  • They receive props as arguments

  • They return JSX (which describes the UI)

  • They can use any JavaScript logic inside

βœ… Props Make Components Reusable

  • Pass different data to the same component

  • Define prop types with TypeScript interfaces

  • Destructure props for cleaner code

βœ… JSX Is JavaScript

  • Use {} to embed any JavaScript expression

  • className not class

  • Conditional rendering with ternary or && operators

βœ… Composition Over Complexity

  • Build small, focused components

  • Compose them together to create complex UIs

  • Each component should do one thing well

βœ… TypeScript Saves Time

  • Define interfaces for props to catch errors early

  • Get autocomplete and IntelliSense in your editor

  • Self-documenting code

Common Mistakes I Made (So You Don't Have To)

❌ Forgetting to export the component

❌ Using class instead of className

❌ Forgetting curly braces for JavaScript expressions

❌ Not typing props

Next Steps

We've built a reusable ProductCard component, but it's still static. In the real POS system, I needed users to:

  • Click "Add to Cart" buttons

  • Increase/decrease quantities

  • Respond to user interactions

That requires stateβ€”data that changes over time in response to user actions.

In the next article, we'll add interactivity to our components with useState, building an "Add to Cart" counter that actually works.

Continue to: State & Interactivity

Last updated