published on in blog

Build Better React Native Apps With Container and Presentational Components

As a React or React Native developer, it is important to understand the concept of container and presentational components.

These design patterns help with the proper separation of concerns. You can use this concept to ensure that you structure your code in a more maintainable and scalable way.

What Are Container Components?

Container components, also known as smart components, are responsible for managing data and logic in your app. They handle tasks like fetching data from an API, updating state, and processing user interactions.

To implement this structure, you can use a library such as React-Redux to connect your components to the store and pass data and actions down to your child components or presentational components.

What Are Presentational Components?

Presentational components are responsible for displaying data from their parent components. They are often stateless and focus on the UI and the visual representation of the data.

This state makes them easy to manipulate and test, earning them the name of dumb components. The dumb state of presentational components makes it possible for you to reuse them across your whole application. This avoids lousy and repetitive code.

Why Use Container and Presentational Components?

The short and simple answer to the question is: Separation of Concerns. This is a key principle in several paradigms, including object-oriented, functional, and aspect-oriented programming. However, many React developers tend to ignore these concepts and opt to write code that just works.

Code that just works is great, until it stops working. Poorly organized code is harder to maintain and update. This can make it tricky to add new features or bring in other programmers to work on the project. Fixing these issues once already created is a workload, and they are better prevented from the onset.

Applying the container and presentational components design pattern ensures that every component within your project has a clear task that it handles. This achieves a modular structure where each optimized component comes together to complete your app.

Your components may still overlap; the division of duties between a container and a presentational component is not always distinct. However, as a general rule, you should focus your presentational components on visual data, and your container components on data and logic.

How to Use Container and Presentational Components in React Native

In a typical React Native app, it is common to create components that contain both presentational and logic-related code. You might fetch data from an API, manage the state of a form, and display output all in one class. Consider a simple app that will fetch a list of users from an API and display their names and age.

You can do this with a single component, but it will result in code that is difficult to read, not reusable, and harder to test and maintain.

For example:

import React, { useState, useEffect } from 'react';
import { View, Text, FlatList } from 'react-native';

const UserList = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const response = await fetch('https://example.com/users');
      const data = await response.json();
      setUsers(data);
    };

    fetchUsers();
  }, []);

  return (
    <FlatList
      data={users}
      keyExtractor={item => item.id}
      renderItem={({ item }) => (
        <View>
          <Text>Name: {item.name}</Text>
          <Text>Age: {item.age}</Text>
        </View>
      )}
    />
  );
};

export default UserList;

In this example, UserList is responsible for managing the state of an input field, fetching data from an API, and rendering the data.

The better and more efficient way to implement this is to separate the logic in UserList into presentation and container components.

You can create a UserListContainer component that is responsible for fetching and managing the user data. It can then pass this data to a presentational component, UserList, as a prop.

import React, { useState, useEffect } from 'react';

// Container Component
const UserListContainer = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const response = await fetch('https://example.com/users');
      const data = await response.json();
      setUsers(data);
    };

    fetchUsers();
  }, []);

  return <UserList users={users} />;
};

export default UserListContainer;

You can separate the presentation between two presentational components: User and UserList. Each is responsible for simply generating markup based on input props they receive.

import { View, Text, FlatList } from 'react-native';

// Presentational Component
const User = ({ name, age }) => (
  <View>
    <Text>Name: {name}</Text>
    <Text>Age: {age}</Text>
  </View>
);

// Presentational Component
const UserList = ({ users }) => (
  <FlatList
    data={users}
    keyExtractor={item => item.id}
    renderItem={({ item }) => <User name={item.name} age={item.age} />}
  />
);

The new code separates the original component into two presentational components, User and UserList, and one container component, UserListContainer.

Best Practices for Implementing Container and Presentational Components

When you use container and presentational components, it's important to follow some best practices to ensure that the components work as intended.

  • Each component should have a clear and specific role. The container component should manage state and the presentational component should handle visual presentation.
  • Where possible, use functional components instead of class components. They are simpler, easier to test, and provide better performance.
  • Avoid including logic or functionality in a component that is irrelevant to its purpose. This helps to keep components focused and easy to maintain and test.
  • Use props for communication between components, clearly separating concerns and avoiding tightly-coupled components.
  • Unnecessary updates to state can lead to performance issues, so it's important to only update state when necessary.
  • Following these best practices ensures that your container and presentational components work together effectively to provide a clean, organized, and scalable solution for managing state and visual presentation in your React Native app.

    The Benefits of Using Container and Presentational Components

    Container and Presentational Components can provide several benefits. They can help improve your code structure, maintainability, and scalability. They also result in better collaboration and delegation of tasks among teams. They can even lead to increased performance and optimization of your React Native app.

    Follow best practices for implementing these components, and you can build better and more scalable React Native apps.

    ncG1vNJzZmivp6x7rq3KnqysnZ%2Bbe6S7zGipnpmTqXqvrdOirZ5lkaW9tHnCqKWtmZmjsrN5z6ucrJ2eqa61tc6nmKVlk6S6sbvNnqWtq12Xwqq4w2aZnqykmr9w