DEV Community

Cover image for Thinking in React: A Beginner’s Journey
Manisha Mardi
Manisha Mardi

Posted on

Thinking in React: A Beginner’s Journey

Building user interfaces with React involves a structured approach that enhances both development efficiency and code maintainability. This guide delves into essential concepts and methodologies to help beginners navigate React development effectively. Here, I’ll share my key learnings, sprinkled with simple examples to help you get started.


1. Breaking the UI into a Component Hierarchy

React applications are like puzzles: you need to identify the pieces before assembling them. Breaking down your UI into components helps you modularize the design and focus on reusability.

Example:

Imagine building a shopping cart interface. Here’s how I approached it:

  • Parent Component: ShoppingCart
  • Child Components: CartItem, CartSummary, PromoCodeForm

Each component has a specific responsibility. For example, CartItem handles the display of individual items, while CartSummary calculates the total price. Starting with a sketch or mockup makes this process easier.


2. Building a Static Version

Before diving into state and interactivity, it’s crucial to create a static version of your application. This step focuses solely on rendering the UI based on fixed data.

Example:

If the shopping cart has three items, render them using hardcoded data:

function CartItem({ name, price }) {
  return (
    <div>
      <p>{name}</p>
      <p>${price}</p>
    </div>
  );
}

function ShoppingCart() {
  return (
    <div>
      <CartItem name="T-shirt" price={20} />
      <CartItem name="Jeans" price={40} />
      <CartItem name="Shoes" price={60} />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

This approach ensures the UI layout is solid before you integrate logic.


3. Identifying Minimal State

State is the dynamic part of React. Deciding what should be stateful is essential. The rule of thumb is:

  • If data changes over time, it’s state.
  • If data is passed unchanged from parent to child, it’s a prop.

Example:

In the shopping cart, the promo code and quantity are stateful because they can change. However, the product names and prices are static data (props).

function PromoCodeForm({ promoCode, setPromoCode }) {
  return (
    <input
      type="text"
      value={promoCode}
      onChange={(e) => setPromoCode(e.target.value)}
      placeholder="Enter Promo Code"
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

Here, the promoCode state is managed in the parent component and updated via setPromoCode.


4. Adding Inverse Data Flow

React’s unidirectional data flow ensures clarity, but sometimes child components need to update parent state. This is achieved using callback functions.

Example:

If the user updates the quantity of a cart item, the parent component’s state should reflect the change:

function CartItem({ name, price, quantity, onQuantityChange }) {
  return (
    <div>
      <p>{name}</p>
      <p>${price}</p>
      <input
        type="number"
        value={quantity}
        onChange={(e) => onQuantityChange(e.target.value)}
      />
    </div>
  );
}

function ShoppingCart() {
  const [cart, setCart] = React.useState([
    { id: 1, name: "T-shirt", price: 20, quantity: 1 },
    { id: 2, name: "Jeans", price: 40, quantity: 1 },
  ]);

  const handleQuantityChange = (id, newQuantity) => {
    setCart((prevCart) =>
      prevCart.map((item) =>
        item.id === id ? { ...item, quantity: newQuantity } : item
      )
    );
  };

  return (
    <div>
      {cart.map((item) => (
        <CartItem
          key={item.id}
          name={item.name}
          price={item.price}
          quantity={item.quantity}
          onQuantityChange={(newQuantity) =>
            handleQuantityChange(item.id, newQuantity)
          }
        />
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

5. Adding Interactivity

With state in place, interactivity comes to life. Event handlers like onClick or onChange can update the state, making the application dynamic.

Example:

Adding a "Remove Item" button in the cart:

<button onClick={() => handleRemoveItem(item.id)}>Remove</button>
Enter fullscreen mode Exit fullscreen mode

The handleRemoveItem function filters the item out of the cart array and updates the state.


6. Props vs State

This was a game-changer for me. Props are read-only and flow from parent to child, while state is managed within the component. Understanding this distinction helped me debug faster and design better components.

Quick Rule:

  • Use props for immutable data.
  • Use state for data that needs to change.

7. Top-Down vs Bottom-Up Development

Both approaches have their place:

  • Top-Down: Start with the big picture and drill down into smaller components.
  • Bottom-Up: Build foundational components first and integrate them into the larger structure.

For simple apps, I prefer top-down. For complex projects, bottom-up ensures I get the basics right.


8. Iterative Development

React shines when you build incrementally. Start simple, test often, and refine as you go.

Example:

  • First, render a static product list.
  • Next, add filtering functionality.
  • Finally, enable sorting or search features.

Each step builds on the last, ensuring a robust application.


Final Thoughts

Thinking in React transformed how I approach front-end development. By breaking problems into manageable parts and iterating step-by-step, I’ve been able to build applications that are not only functional but also maintainable.

If you’re just starting out, embrace this systematic approach. Trust me, it will save you countless headaches and make you a better developer.

Let me know your thoughts! How do you approach building React applications?

Top comments (0)