Understanding the React component hierarchy and composition

Last updated : Jul 30, 2023 12:00 AM

The previous tutorial explained how to build your first React Js application from scratch.

React Js simplifies creating complex UIs by breaking them down into smaller, reusable components. This article will explore the React component hierarchy and composition to help beginners understand how to structure their React applications effectively.

1. React Components

A React component is a self-contained piece of code. A component is responsible for rendering a part of a user interface. Components can be written as JavaScript functions or classes. They take inputs, called props, similar to Javascript functions that take parameters. Components return React elements that describe the UI.

Simple ReactJs componentDescription
export const TextInput = () => {
    return (
        <div className="form-field">
            <label htmlFor="name">Name</label>
            <input type="text" id="name" name="name" required />
        </div>
    )
}
Simple ReactJs componentDescription
export const Button = () => {
    return (
    	<button type="submit">Submit</button>
    )
}

The above two components take no props and return HTML representing user input with a label and a button. But the label Name, input attributes, and button value are static. I have no way to change them. That's where the props come in handy.

2. Component Hierarchy

React applications are built using a tree-like structure of components. A parent component can contain one or more child components, which can have their children forming a hierarchy.

Component HierarchyDescription
import { Button } from "./Button";
import { TextInput } from "./TextInput";
export const SignupForm = () => {
    return (
        <div className="signup-form">
        <h1>Signup Form</h1>
        <form>
          <TextInput/>
          <TextInput/>
          <Button/>
        </form>
      </div>
    )
}

My Signup form uses the TextInput and Button components in the above example. Likewise, the TextInput and the Button components may have their children. Now I want to customize my components to represent the necessary elements of a signup form. Let's take a look at how props work to solve that issue.

3. Passing Data through Props

In React, props is short for properties. Props refers to how a component receives data to carry out its intended operation. Components receive props from their parent component. Therefore Props provide a mechanism to pass data and even functions down the component tree. That allows communication between components. They make components more flexible and reusable by enabling them to accept different inputs and render accordingly.

Here are the modified version of TextInput and Button components that accept props to decide how it should render.

Receiving dataDescription
export const TextInput = (props) => {
    return (
        <div className="form-field">
            <label htmlFor="name">{props.label}</label>
            <input type={props.inputType} id={props.id} name={props.name} required />
        </div>
    )
}
Receiving dataDescription
export const Button = (props) => {
    return (
    	<button type="submit">{props.value}</button>
    )
}

When a component receives data through props, it becomes a controlled component. The component is controlled by the parent component that passes the data.

When a child component accepts props, the parent component must provide all the required props to its child components. Now I can re-write my signup form with child components that accept props.

Passing data to child componentsDescription
import { Button } from "./Button";
import { TextInput } from "./TextInput";

export const SignupForm = () => {
    return (
        <div className="signup-form">
        <h1>Signup Form</h1>
        <form>
          <TextInput label="User Name" id="name" name="name" inputType="text"/>
          <TextInput label="Password" id="password" name="password" inputType="password"/>
          <Button value="Submit"/>
        </form>
      </div>
    )
}

In the above example, the parent component SignupForm controls how the child components TextInput and Button should display by providing the necessary data through props.

4. Component Composition

React promotes the concept of composition. Composition means building more complex components by combining simpler ones. This approach enables code reusability and makes managing and maintaining the application easier.

The signup form I discussed above is a good example of composition. I built the signup form by combining TextInput and Button. Below is another example of composition in React Js.

Component CompositionDescription
export const SignupForm = () => {
    return (
        <div className="signup-form">
        <h1>Signup Form</h1>
        <form>
          <TextInput type="text"/>
          <TextInput type="password"/>
          <Input type="check"/>
          <TermsAndConditions/>
          <Button value="Submit"/>
        </form>
      </div>
    )
}

5. Container and Presentational Components

React components can be divided into two categories.

  1. Container components.
  2. Presentational components.

Container components manage data and state, while presentational components focus on rendering the UI based on the received props. That is more of a design pattern approach.

Container componentDescription
const DisplayContainer = (props) => {
	/*
		Do some processing/calculations on
		cardsToDisplay variable
	*/
	return <Display cards={cardsToDisplay} />
}
Presentational componentDescription
const Display = (props) => {
	return (
		props.cardsToDisplay.map((card) => {
			<div>{card.text}</div>
		})
	)
}
Lance

By: Lance

Hi, I'm Lance Raney, a dedicated Fullstack Developer based in Oklahoma with over 15 years of exp

Read more...