Render props

В Chakra UI концепция render props применяется для передачи функций как дочерних компонентов, позволяя динамически управлять внутренним состоянием компонента и его поведением. Render props — это паттерн, где дочерний компонент является функцией, возвращающей JSX. Такой подход особенно полезен для создания настраиваемых компонентов, которые могут менять визуализацию в зависимости от состояния, без необходимости вручную управлять этим состоянием извне.

Пример базового использования:

import { Menu, MenuButton, MenuList, MenuItem } from "@chakra-ui/react";
import { ChevronDownIcon } from "@chakra-ui/icons";

function ExampleMenu() {
  return (
    <Menu>
      {({ isOpen }) => (
        <>
          <MenuButton>
            Меню {isOpen ? "▲" : "▼"}
          </MenuButton>
          <MenuList>
            <MenuItem>Пункт 1</MenuItem>
            <MenuItem>Пункт 2</MenuItem>
          </MenuList>
        </>
      )}
    </Menu>
  );
}

Здесь Menu принимает функцию как дочерний элемент, в которую передаются внутренние состояния компонента (isOpen). Это позволяет управлять визуальной частью меню в зависимости от состояния открытости.


Управление состоянием через Render Props

Render props предоставляет доступ к различным состояниям компонента, таким как:

  • isOpen — открыто или закрыто состояние.
  • onClose и onOpen — функции для изменения состояния.
  • isActive или isHovered — состояния взаимодействия пользователя.

Пример с управлением состоянием isOpen для модального окна:

import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalFooter, Button } from "@chakra-ui/react";

function ExampleModal() {
  return (
    <Modal>
      {({ isOpen, onClose }) => (
        <>
          <Button onCl ick={onClose}>Закрыть</Button>
          <ModalOverlay />
          <ModalContent>
            <ModalHeader>Заголовок</ModalHeader>
            <ModalBody>
              Содержимое модального окна
            </ModalBody>
            <ModalFooter>
              <Button colorScheme="blue" onCl ick={onClose}>Закрыть</Button>
            </ModalFooter>
          </ModalContent>
        </>
      )}
    </Modal>
  );
}

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


Комбинирование Render Props с кастомными компонентами

Render props легко сочетаются с кастомными компонентами для расширенной функциональности. Например, создание кнопки с динамическим стилем при наведении и нажатии:

import { Box, useDisclosure } from "@chakra-ui/react";

function CustomButton({ children }) {
  const { isOpen, onToggle } = useDisclosure();
  
  return (
    <Box
      as="button"
      onCl ick={onToggle}
      bg={isOpen ? "blue.500" : "gray.300"}
      color="white"
      p={4}
      borderRadius="md"
    >
      {children({ isOpen })}
    </Box>
  );
}

function App() {
  return (
    <CustomButton>
      {({ isOpen }) => (isOpen ? "Активно" : "Не активно")}
    </CustomButton>
  );
}

В этом примере дочерняя функция получает текущее состояние isOpen и изменяет отображаемый текст в зависимости от него. Render props делают компонент гибким и легко настраиваемым.


Render Props и анимации

Использование render props в сочетании с библиотекой Framer Motion, часто применяемой вместе с Chakra UI, позволяет анимировать элементы в зависимости от их состояния:

import { Box, useDisclosure } from "@chakra-ui/react";
import { motion } from "framer-motion";

function AnimatedBox() {
  const { isOpen, onToggle } = useDisclosure();
  
  return (
    <Box as={motion.div}
         onCl ick={onToggle}
         animate={{ scale: isOpen ? 1.2 : 1 }}
         bg="teal.400"
         w="100px"
         h="100px"
         borderRadius="md"
    />
  );
}

Здесь состояние isOpen управляет масштабом элемента, а render props могут быть использованы для передачи дополнительных параметров внутрь дочерней функции.


Рекомендации по использованию Render Props в Chakra UI

  1. Минимизировать глубину вложенности: Render props позволяют управлять состоянием без создания лишних компонентов, но чрезмерная вложенность функций усложняет чтение кода.
  2. Использовать для состояния и взаимодействий: Render props лучше всего подходят для компонентов, где нужно контролировать открытие/закрытие, активное состояние или анимацию.
  3. Комбинировать с useDisclosure: Chakra UI предоставляет удобный хук useDisclosure, который идеально сочетается с render props для управления состоянием.
  4. Передавать параметры внутрь дочерней функции: Это позволяет делать компонент максимально универсальным и переиспользуемым.

Render props в Chakra UI — это мощный инструмент для создания динамических и настраиваемых интерфейсов. Они позволяют полностью контролировать внутренние состояния компонентов, комбинируются с хуками и анимациями, обеспечивая гибкость и масштабируемость UI.