DEV Community

Cover image for Mastering React Patterns: Presentational and Container Components
Samuel C. Okanume
Samuel C. Okanume

Posted on • Edited on

Mastering React Patterns: Presentational and Container Components

Introduction: In the world of React development, understanding patterns and best practices is crucial for building robust and maintainable applications. One essential pattern is the separation of components into Presentational and Container components. In this article, we will delve into the concepts of Presentational and Container components, explore their benefits, and provide real-world examples of how they can be used effectively.

Target Audience:

This article is suitable for both beginner and experienced React developers who want to enhance their understanding of React patterns and improve the structure of their applications.

Learning Objectives:

By the end of this article, you will gain the following skills:

  • Recognize the role of Presentational components and Container components.

  • Create Presentational components and Container components.

  • Understand how to use Presentational and Container components in a React application.

  • Comprehend the benefits and use cases of each component type.

  • Apply best practices for structuring React applications.

Presentational Components:

Presentational components focus on the visual representation of data and are responsible for how things look in a React application. They have the following characteristics:

  • Concerned with the user interface and rendering data.

  • Stateless components with no or minimal internal state.

  • Receive data exclusively through props.

  • Usually implemented as functional components.

  • Promote code reusability and maintainability.

  • Emphasize separation of concerns, readability, and testability.

  • Prefer composition over inheritance.

  • Follow declarative programming principles.

  • Encourage immutability for easier reasoning and preventing rendering errors.

Let's explore an example of a Presentational component:

const Button = ({ label, handler }) => {
  return (
    <button className="btn" onClick={handler}>
      {label}
    </button>
  );
};

const Persons = ({ names }) => {
  return (
    <ul>
      {names.map((name) => (
        <li key={name}>{name}</li>
      ))}
    </ul>
  );
};
Enter fullscreen mode Exit fullscreen mode

In the above code, we have a Button component that represents a reusable button with a click event handler, and a Persons component that displays a list of names. These components receive data through props and are focused on rendering the UI.

Container Components:

Container components handle the logic and state management of a React application. They orchestrate the interaction between Presentational components and manage the flow of data. Key characteristics of Container components include:

  • Focus on the functionality and behavior of the application.

  • Render Presentational components and pass them data and callbacks.

  • Maintain the application's state and manage data flow.

  • Enable code reuse and maintainability.

  • Emphasize separation of concerns and readability.

  • Follow declarative programming principles.

  • Ease reasoning about component dependencies.

Let's examine an example of a Container component:

const ClickCounter = () => {
  const [counter, setCounter] = useState(0);

  const addCounter = () => {
    setCounter(counter + 1);
  };

  return (
    <div>
      <Button label="Increment" handler={addCounter} />
      Clicked {counter} times
    </div>
  );
};

const Form = () => {
  const [name, setName] = useState("");
  const [namesList, setNamesList] = useState([]);

  const onSave = () => {
    setNamesList([...namesList, name]);
    setName("");
  };

  return (
    <div>
      <form>
        Enter Name:
        <input type="text" onChange={(e) => setName(e.target.value)} />
        <Button label="Save" handler={onSave} />
      </form>
      <Persons names={namesList} />
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

In this example, the ClickCounter component maintains its own state and renders the Button component as a child. The Form component manages form input, state, and data flow, rendering the Button and Persons components as children. The Container components handle the application logic while utilizing Presentational components for UI rendering.

Real-World Use Cases:

To illustrate the benefits of Presentational and Container components, let's consider a real-world scenario. Suppose you are building a complex application that requires displaying a list of products. The ProductList component, responsible for rendering the list, can be a Presentational component that receives the product data as props. The ProductPage component, responsible for fetching the product data and handling user interactions, can be a Container component that manages the state and data flow, rendering the ProductList component.

By separating concerns and encapsulating logic, Presentational and Container components promote reusability, maintainability, and code readability.

Best Practices and Tips:

To effectively implement Presentational and Container components in your React applications, consider the following best practices:

  • Maintain a clear separation between Presentational and Container components.

  • Keep Presentational components as simple as possible, focusing on rendering UI based on props.

  • Offload business logic and state management to Container components.

  • Utilize the props and callback functions to pass data and handle user interactions between components.

  • Follow naming conventions and folder structure that align with the component types.

  • Write comprehensive tests for both Presentational and Container components.

Conclusion:

In this article, we explored the concepts of Presentational and Container components, their characteristics, benefits, and use cases. By implementing these patterns in your React applications, you can achieve better code organization, maintainability, and reusability. Understanding the separation of concerns between Presentational and Container components empowers you to build scalable and well-structured React applications. Happy coding!

Top comments (0)