ReactJS - Nested Components: A Beginner's Guide

Hello there, future React wizards! Today, we're going to embark on an exciting journey into the world of nested components in ReactJS. Don't worry if you're new to programming – I'll be your friendly guide, explaining everything step by step. By the end of this tutorial, you'll be nesting components like a pro!

ReactJS - Nested Components

What are Nested Components?

Before we dive in, let's understand what nested components are. Imagine you're building a house (your React app). The walls, roof, and foundation are your main components. But inside the house, you have rooms (nested components) that can contain furniture (more nested components). This structure allows us to create complex UIs in a manageable way.

Why Use Nested Components?

  1. Reusability: Create components once, use them multiple times.
  2. Maintainability: Easier to update and manage smaller, focused components.
  3. Readability: Your code becomes more organized and easier to understand.

Now, let's get our hands dirty with some code!

Creating Our First Nested Component

We'll start with a simple example. Imagine we're building a shopping app. We'll create a Product component that will contain a Price component.

// Product.js
import React from 'react';
import Price from './Price';

function Product({ name, price }) {
  return (
    <div className="product">
      <h2>{name}</h2>
      <Price amount={price} />
    </div>
  );
}

export default Product;

// Price.js
import React from 'react';

function Price({ amount }) {
  return <p className="price">${amount.toFixed(2)}</p>;
}

export default Price;

In this example, Product is our parent component, and Price is nested inside it. Let's break it down:

  1. We import the Price component into Product.
  2. The Product component receives name and price as props.
  3. We use the Price component inside Product, passing the price prop as amount.

Now, when we use the Product component:

<Product name="Super Cool Gadget" price={19.99} />

It will render:

<div class="product">
  <h2>Super Cool Gadget</h2>
  <p class="price">$19.99</p>
</div>

Isn't that neat? We've created a reusable price display that we can use in any product!

FormattedMoney Component

Now, let's create a more advanced nested component for formatting money. This will be useful for displaying prices in different currencies.

// FormattedMoney.js
import React from 'react';

function FormattedMoney({ amount, currency = 'USD' }) {
  const formatter = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: currency,
  });

  return <span className="formatted-money">{formatter.format(amount)}</span>;
}

export default FormattedMoney;

// Product.js (updated)
import React from 'react';
import FormattedMoney from './FormattedMoney';

function Product({ name, price, currency }) {
  return (
    <div className="product">
      <h2>{name}</h2>
      <FormattedMoney amount={price} currency={currency} />
    </div>
  );
}

export default Product;

Let's break down what's happening in FormattedMoney:

  1. We use the Intl.NumberFormat API to format our number as currency.
  2. We set a default currency of 'USD' using parameter default values.
  3. The component returns a span with the formatted amount.

Now we can use our Product component like this:

<Product name="Amazing Widget" price={29.99} currency="EUR" />

This will render:

<div class="product">
  <h2>Amazing Widget</h2>
  <span class="formatted-money">€29.99</span>
</div>

Cool, right? We've created a flexible, reusable component for displaying prices in different currencies!

FormattedDate Component

Let's create one more nested component to display formatted dates. This could be useful for showing product release dates or sale end dates.

// FormattedDate.js
import React from 'react';

function FormattedDate({ date, format = 'long' }) {
  const options = {
    short: { month: 'short', day: 'numeric', year: 'numeric' },
    long: { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' },
  };

  const formatter = new Intl.DateTimeFormat('en-US', options[format]);

  return <span className="formatted-date">{formatter.format(new Date(date))}</span>;
}

export default FormattedDate;

// Product.js (updated again)
import React from 'react';
import FormattedMoney from './FormattedMoney';
import FormattedDate from './FormattedDate';

function Product({ name, price, currency, releaseDate }) {
  return (
    <div className="product">
      <h2>{name}</h2>
      <FormattedMoney amount={price} currency={currency} />
      <p>Release Date: <FormattedDate date={releaseDate} /></p>
    </div>
  );
}

export default Product;

In this FormattedDate component:

  1. We create two format options: 'short' and 'long'.
  2. We use Intl.DateTimeFormat to format the date based on the chosen format.
  3. We parse the input date string into a Date object.

Now we can use our updated Product component like this:

<Product 
  name="Futuristic Gizmo" 
  price={99.99} 
  currency="USD" 
  releaseDate="2023-12-25"
/>

This will render:

<div class="product">
  <h2>Futuristic Gizmo</h2>
  <span class="formatted-money">$99.99</span>
  <p>Release Date: <span class="formatted-date">Monday, December 25, 2023</span></p>
</div>

Putting It All Together

Let's create a ProductList component that uses all of our nested components:

// ProductList.js
import React from 'react';
import Product from './Product';

function ProductList({ products }) {
  return (
    <div className="product-list">
      {products.map(product => (
        <Product 
          key={product.id}
          name={product.name}
          price={product.price}
          currency={product.currency}
          releaseDate={product.releaseDate}
        />
      ))}
    </div>
  );
}

export default ProductList;

Now we can use our ProductList like this:

const products = [
  { id: 1, name: "Super Gadget", price: 49.99, currency: "USD", releaseDate: "2023-06-15" },
  { id: 2, name: "Mega Widget", price: 39.99, currency: "EUR", releaseDate: "2023-07-01" },
  { id: 3, name: "Awesome Gizmo", price: 59.99, currency: "GBP", releaseDate: "2023-08-30" },
];

<ProductList products={products} />

This will render a list of products, each with formatted prices and dates!

Conclusion

Congratulations! You've just learned about nested components in React. We've created reusable components for formatting money and dates, and nested them within a product component. This is just the beginning – the possibilities with nested components are endless!

Remember, practice makes perfect. Try creating your own nested components and see how they can make your React apps more modular and maintainable.

Happy coding, future React masters! ?

Component Purpose Props
FormattedMoney Display formatted currency amount, currency
FormattedDate Display formatted dates date, format
Product Display product information name, price, currency, releaseDate
ProductList Display a list of products products (array)

Credits: Image by storyset