Написание React-компонентов — целое искусство. Дело не только в том, чтобы заставить их работать, но и в том, чтобы заставить их работать хорошо. Рассмотрим, как профессионально создавать компоненты, уделяя особое внимание читабельности, возможности повторного использования и эффективности.

Создание компонента списка

Начнем с создания базового компонента List (компонента списка):

// src/components/List.js
import React from 'react';

const List = ({ data }) => {
  return (
    <ul>
      {data.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
};

export default List;

Этот компонент принимает массив data и отображает его в виде списка.

Усовершенствование компонентов с помощью HOC

HOC (Higher-Order Components — компоненты высшего порядка) — мощный шаблон для повторного использования логики компонентов. Он оборачивает компонент, расширяя его функциональность без изменения структуры.

Например, HOC withLoading можно использовать для отображения состояния загрузки:

// src/hocs/withLoading.js
import React, { useState } from 'react';

function withLoading(Component) {
  return function WithLoading({ isLoading, ...props }) {
    if (isLoading) {
      return <div>Loading...</div>;
    }
    return <Component {...props} />;
  };
}

export default withLoading;

Этот HOC проверяет параметр isLoading. Если значение параметра “true” (“истинное”), то выводится сообщение “Loading…” (“Загрузка…”). В противном случае HOC отображает обернутый компонент, обеспечивая бесперебойную работу пользователя во время получения данных.

Аналогично работает withErrorHandling — еще один HOC, который может управлять состояниями ошибок:

// src/hocs/withErrorHandling.js
import React from 'react';

function withErrorHandling(Component) {
  return function WithErrorHandling({ error, ...props }) {
    if (error) {
      return <div>Error: {error.message}</div>;
    }
    return <Component {...props} />;
  };
}

export default withErrorHandling;

При возникновении ошибки withErrorHandling выводит сообщение об ошибке. В противном случае компонент отображается как обычно. Этот HOC особенно полезен для обработки ошибок получения данных или проблем в жизненном цикле компонента.

Комбинирование withLoading и withErrorHandling позволяет создать надежный компонент, который элегантно обрабатывает как состояния загрузки, так и состояния ошибки. Такой подход способствует повторному использованию кода и разделению задач, делая компоненты более удобными для обслуживания и простыми для понимания.

Получение данных с помощью хуков

React-хуки позволяют использовать состояние и другие возможности React без написания класса. useFetch — пользовательский хук, который получает данные из API:

// src/hooks/useFetch.js
import { useState, useEffect } from 'react';

const useFetch = (url) => {
  const [data, setData] = useState([]);
  const [isLoading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        const json = await response.json();
        setData(json);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    // Функция очистки 
    return () => {
      // Логика очистки (при необходимости)
    };
  }, [url]);

  return { data, isLoading, error };
};

export default useFetch;

Он обрабатывает состояние получения, хранение данных и ошибки, облегчая получение и отображение данных в компонентах.

Сборка приложения

Теперь прибегнем к помощи HOC’ов и хуков для сборки компонента App:

// src/App.js
import React from 'react';
import withLoading from './hocs/withLoading';
import withErrorHandling from './hocs/withErrorHandling'; // Добавлен новый HOC
import useFetch from './hooks/useFetch';
import List from './components/List';

const ListWithLoading = withLoading(List);
const ListWithErrorHandling = withErrorHandling(ListWithLoading); // Используется для добавления обработки ошибок в компонент ListWithLoading

const App = () => {
  const { data, isLoading, error } = useFetch('https://api.example.com/data');

  return (
    <div>
      <h1>List Component</h1>
      <ListWithErrorHandling data={data} isLoading={isLoading} error={error} /> {/* Передает состояние ошибки компоненту ListWithLoading */}
    </div>
  );
};

export default App;

Хук useFetch использован для загрузки данных и передачи их в компонент List, который дополнен возможностями загрузки и обработки ошибок с помощью соответствующих HOC’ов.

Заключение

Писать компоненты на профессиональном уровне — значит думать об общей картине. Речь идет о создании компонентов, которые легко читать, поддерживать и повторно использовать. Используя такие паттерны, как HOC и хуки, можно создать чистую и эффективную кодовую базу, которая выдержит испытание временем.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Selcuk Ozdemir: Write a React Component Like a Pro

Предыдущая статьяМоделирование лесных пожаров