Переиспользуемые компоненты

Chakra UI предоставляет мощный инструмент для разработки React-приложений с модульной и настраиваемой системой компонентов. Ключевым аспектом эффективной работы с библиотекой является умение создавать переиспользуемые компоненты, которые легко интегрируются в разные части приложения и поддерживают единый дизайн.

Использование Box и Flex как базовых строительных блоков

В Chakra UI Box и Flex являются универсальными контейнерами, на которых можно строить практически любые UI-элементы. Благодаря их свойствам можно создавать компоненты, которые автоматически наследуют стили и адаптируются под контекст:

import { Box, Flex, Text } from '@chakra-ui/react';

function Card({ title, content }) {
  return (
    <Box borderWidth="1px" borderRadius="lg" p={4} boxShadow="md">
      <Text fontSize="xl" fontWeight="bold">{title}</Text>
      <Text mt={2}>{content}</Text>
    </Box>
  );
}

function CardList({ items }) {
  return (
    <Flex direction="column" gap={4}>
      {items.map((item, index) => <Card key={index} {...item} />)}
    </Flex>
  );
}

В этом примере Card становится полностью переиспользуемым компонентом, который можно использовать в разных контекстах, а CardList демонстрирует композицию нескольких компонентов.

Использование props для настройки компонентов

Одна из сильных сторон Chakra UI — это возможность управлять стилями компонентов через пропсы. Это позволяет создавать универсальные компоненты, которые легко настраиваются:

function ButtonPrimary({ children, colorScheme = 'blue', size = 'md', ...rest }) {
  return (
    <Button colorScheme={colorScheme} size={size} {...rest}>
      {children}
    </Button>
  );
}

Здесь ButtonPrimary принимает пропсы colorScheme и size, что позволяет изменять его внешний вид без дублирования кода.

Тема и extendTheme для глобальной стилизации

Для переиспользуемых компонентов важно сохранить единый стиль приложения. Chakra UI позволяет расширять тему с помощью extendTheme:

import { extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  components: {
    Button: {
      baseStyle: {
        fontWeight: 'bold',
        borderRadius: 'md',
      },
      sizes: {
        lg: { fontSize: 'lg', px: 8, py: 6 },
        sm: { fontSize: 'sm', px: 4, py: 2 },
      },
      variants: {
        primary: { bg: 'blue.500', color: 'white', _hover: { bg: 'blue.600' } },
        secondary: { bg: 'gray.200', color: 'black', _hover: { bg: 'gray.300' } },
      },
    },
  },
});

export default theme;

С помощью темы можно задать глобальные стили для всех компонентов, что делает переиспользуемые компоненты единообразными по всему приложению.

Создание пользовательских компонентов с forwardRef

Для интеграции переиспользуемых компонентов в сложные структуры удобно использовать forwardRef, что позволяет передавать ссылку на DOM-элемент:

import { forwardRef } from 'react';
import { Input } from '@chakra-ui/react';

const InputField = forwardRef(({ label, ...props }, ref) => (
  <Box>
    {label && <Text mb={2}>{label}</Text>}
    <Input ref={ref} {...props} />
  </Box>
));

forwardRef делает компонент совместимым с формами и библиотеками управления фокусом, обеспечивая высокую гибкость.

Композиция компонентов и HOC

Chakra UI поддерживает композицию компонентов, что позволяет создавать более сложные элементы из простых базовых блоков:

function CardWithButton({ title, content, buttonText, onClick }) {
  return (
    <Card title={title} content={content}>
      <ButtonPrimary onCl ick={onClick}>{buttonText}</ButtonPrimary>
    </Card>
  );
}

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

Стилизация через sx и css пропсы

Для локальных и уникальных стилей можно использовать проп sx или css, что обеспечивает гибкость при сохранении основного дизайна:

<Box
  sx={{
    border: '1px solid',
    borderColor: 'gray.300',
    borderRadius: 'md',
    p: 4,
    _hover: { bg: 'gray.50' },
  }}
>
  Контент блока
</Box>

Поддержка темной и светлой темы

Переиспользуемые компоненты в Chakra UI легко адаптируются под разные цветовые схемы благодаря useColorModeValue:

import { useColorModeValue } from '@chakra-ui/react';

function ThemedCard({ children }) {
  const bg = useColorModeValue('white', 'gray.700');
  return <Box bg={bg} p={4} borderRadius="md">{children}</Box>;
}

Такой подход позволяет компонентам автоматически менять внешний вид в зависимости от текущей темы.

Переиспользование логики через кастомные хуки

Для увеличения переиспользуемости можно отделять логику от представления, создавая кастомные хуки:

import { useState } from 'react';

function useToggle(initial = false) {
  const [state, setState] = useState(initial);
  const toggle = () => setState(!state);
  return [state, toggle];
}

function ToggleButton() {
  const [isOn, toggle] = useToggle();
  return <Button onCl ick={toggle}>{isOn ? 'Включено' : 'Выключено'}</Button>;
}

Это позволяет повторно использовать логику в разных компонентах без дублирования кода.

Итоговые рекомендации

  • Старайтесь разделять логику и визуальное представление компонентов.
  • Используйте тему и глобальные стили для единообразного дизайна.
  • Композиция и пропсы делают компоненты гибкими и легко масштабируемыми.
  • Кастомные хуки и forwardRef обеспечивают совместимость с более сложными сценариями.

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