SOLID in React Native - Part 1
Foto de Caspar Camille Rubin (Unsplash)

SOLID in React Native - Part 1

The acronym SOLID addresses a set of five rules in software design. With these rules, we can create software with better understanding, flexibility, and maintainability. In this post, we will introduce the first of these principles - the Single Responsibility Principle, applied to mobile development with React Native, which can also be applied to any React application.


Single Responsibility Principle (SRP) - "A class ought to serve a single, clearly defined purpose, reducing the need for frequent changes."

Let's observe the ListRepos component below and analyze what it's doing:

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

import axios from 'axios';

type Repo = {
  id: string;
  language: string;
  name: string;
};

export const ListRepos = () => {
  const [repos, setRepos] = useState<Array<Repo>>([]);
  const [isLoading, setIsLoading] = useState<boolean>(true);

  useEffect(() => {
    (async () => {
      try {
        const { data } = await axios.get(
          'https://api.github.com/users/davi1985/repos'
        );

        setRepos(data);
      } catch (error) {
        Alert.alert('Something wrong!');
      } finally {
        setIsLoading(false);
      }
    })();
  }, []);

  if (isLoading) {
    return <ActivityIndicator size={'large'} color={'#4285F4'} />;
  }

  return (
    <View>
      {repos.map((item) => (
        <View key={item.id}>
          <Text>{item.name}</Text>
          <Text>{item.language}</Text>
        </View>
      ))}
    </View>
  );
};        

We can observe that the component is:

  • Performing data fetching,
  • Rendering the list of repositories, and
  • Managing states.

Thinking about SOLID, specifically the SRP, we can separate the responsibilities. First, let's isolate the data fetching part into a hook:

import { useState, useEffect } from 'react';
import { Alert } from 'react-native';

import axios from 'axios';

type Repo = {
  id: string;
  language: string;
  name: string;
};

export const useGetRepos = () => {
  const [repos, setRepos] = useState<Array<Repo>>([]);
  const [isLoading, setIsLoading] = useState<boolean>(true);

  useEffect(() => {
    (async () => {
      try {
        const { data } = await axios.get(
          'https://api.github.com/users/davi1985/repos'
        );

        setRepos(data);
      } catch (error) {
        Alert.alert('Something wrong!');
      } finally {
        setIsLoading(false);
      }
    })();
  }, []);

  return { isLoading, repos };
};        

Now, our ListRepos component is cleaner and has fewer responsibilities, see:

import React from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import { useGetRepos } from './useGetRepos';

export const ListRepos = () => {
  const { isLoading, repos } = useGetRepos();

  if (isLoading) {
    return <ActivityIndicator size={'large'} color={'#4285F4'} />;
  }

  return (
    <View>
      {repos.map((item) => (
        <View key={item.id}>
          <Text>{item.name}</Text>
          <Text>{item.language}</Text>
        </View>
      ))}
    </View>
  );
};        

We can further improve. If we observe, each item in our list is being rendered directly in our main component. We can separate it and pass via props what is necessary for its rendering. Notice:

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

type Props = {
  id: string;
  language: string;
  name: string;
};

export const Repo = ({ id, language, name }: Props) => (
  <View key={id}>
    <Text>{name}</Text>
    <Text>{language}</Text>
  </View>
);        

With our Repo component created, our ListRepos component becomes simpler.

import React from 'react';
import { View, ActivityIndicator } from 'react-native';
import { useGetRepos } from './useGetRepos';
import { Repo } from './Repo';

export const ListRepos = () => {
  const { isLoading, repos } = useGetRepos();

  if (isLoading) {
    return <ActivityIndicator size={'large'} color={'#4285F4'} />;
  }

  return (
    <View>
      {repos.map((item) => (
        <Repo {...item} />
      ))}
    </View>
  );
};        

We can continue to improve. I leave you with some challenges to implement and enhance your understanding of the SRP:

  1. Isolate the Axios call in another file and only call this function in the useGetRepos hook.
  2. The typing of the Repo component is the same as that used in the hook, meaning it's repeating. We can create a @types folder to share types throughout the application.

By implementing the Single Responsibility Principle (SRP) in our React Native development, we can establish a more cohesive and modular structure.

In the next post, we'll address another principle, further deepening our software design practices.


Pritam R.

React Native Developer at Samta.ai

1 年

I create a Whatsapp group for React Native developers to get support and help each others to solve bugs, advice, job searching, etc. https://chat.whatsapp.com/KShEMASv1RjIeakQQW4fPS please join group, So we can get your valuable guidance and support

回复
Eliel Prata Martins

Full-Stack Developer | JavaScript | Python | React Native | Typescript | React | Redux | NodeJs

1 年

Sensacional, conteúdo extremamente relevante quando se trata especialmente da manuten??o do código.

Jeová Júnior

Tech Leader | Full Stack Developer | Next Js | React Js | React Native | NestJS | PHP | SHOPIFY

1 年

Que conteúdo enriquecedor!

Felipe Alves

FullStack Developer | React Native | Expo | React | Node | TypeScript | JavaScript

1 年

muito bom, mano!

Eduardo Rodrigo de Louren?o

Full Stack Developer Senior

1 年

Congratulations David, the article was very educational ??

要查看或添加评论,请登录

Davi Silva的更多文章

  • React Hooks? Ok, mas por que?

    React Hooks? Ok, mas por que?

    No dia 6 de fevereiro de 2019, foi lan?ada a vers?o 16.8 do React, introduzindo os hooks.

  • JavaScript: var, let, and const

    JavaScript: var, let, and const

    If you're a JavaScript developer, you probably use , , or in your code. But do you really know what's happening under…

  • JavaScript, React ? Olha lá hein!

    JavaScript, React ? Olha lá hein!

    Nos últimos anos (quase quatro anos), venho trabalhando exclusivamente com desenvolvimento front-end, escrevendo código…

    4 条评论
  • Entendendo atributos privados no JavaScript/TypeScript

    Entendendo atributos privados no JavaScript/TypeScript

    O JavaScript, sendo uma linguagem de tipagem dinamica, realiza uma inferência automática de tipos. Isso significa que…

  • Understanding mutability and infer in TS

    Understanding mutability and infer in TS

    In this article, we will explain how Typescript works with mutability and inferring typings when you declare variables.…

  • Seven ways to remove elements from Arrays in JS

    Seven ways to remove elements from Arrays in JS

    It's most common when we develop code, in front or in the backend, to need to manipulate data from arrays removing…

  • 5 Javascript concepts every developer should know

    5 Javascript concepts every developer should know

    Every JavaScript developer should be familiar with these features that I am going to show in this article - modern…

  • "b" + "a" + +"a" + "a" ? Banana? What ?

    "b" + "a" + +"a" + "a" ? Banana? What ?

    JavaScript is one of the most important programming languages in the world. Whether you're a front-end or back-end…

    1 条评论
  • Capital letters? Why ?

    Capital letters? Why ?

    Do you work with React? Do you know why React components need to start with capital letters? In JSX, React components…

  • TTFB, TTI, and FCP: Do You Know What These Acronyms Mean?

    TTFB, TTI, and FCP: Do You Know What These Acronyms Mean?

    When discussing front-end applications built with React, we often encounter two primary types: SPAs (Single Page…

社区洞察

其他会员也浏览了