返回

Chakra UI 手风琴交互冲突:深入解析并提出解决方案

javascript

Chakra UI 中解决两列手风琴组件交互冲突

简介

在使用 Chakra UI 和 React 构建应用程序时,你可能会遇到一个棘手的问题:当一个手风琴组件扩展时,另一个手风琴组件也会受到影响。这篇文章将深入探讨这个问题的根源,并提供多种有效的解决方案来防止这种交互冲突。

问题根源

默认情况下,当 Accordion 组件的 allowMultiple 属性设置为 true 时,它允许同时扩展多个手风琴。然而,如果没有显式定义手风琴的交互,当一个手风琴展开时,所有其他手风琴都会自动收起。

解决方案

受控手风琴

使用受控手风琴可以解决此问题,这意味着你手动管理每个手风琴的状态,而不是依赖默认的组件交互。你可以通过使用 isOpen 属性来实现这一点,该属性接受一个布尔值来确定手风琴是否展开。

import { useState } from "react";

const ControlledAccordion = () => {
  const [isExpanded, setIsExpanded] = useState(false);

  return (
    <AccordionItem>
      <h2>
        <AccordionButton onClick={() => setIsExpanded(!isExpanded)}>
          <Box as="span" flex="1" textAlign="left">
            Section 1 title
          </Box>
          <AccordionIcon />
        </AccordionButton>
      </h2>
      <AccordionPanel pb={4} isOpen={isExpanded}>
        ...
      </AccordionPanel>
    </AccordionItem>
  );
};

Context API

另一个解决方法是使用 context API。通过创建一个共享手风琴状态的 context,你可以防止其他手风琴受到影响。在所有手风琴组件中提供这个 context。

import { createContext, useContext } from "react";

const AccordionContext = createContext(null);

const Accordion = () => {
  const [activeIndex, setActiveIndex] = useState(null);

  return (
    <AccordionContext.Provider value={{ activeIndex, setActiveIndex }}>
      ...
    </AccordionContext.Provider>
  );
};

const AccordionItem = () => {
  const { activeIndex, setActiveIndex } = useContext(AccordionContext);

  return (
    <AccordionItem>
      <h2>
        <AccordionButton onClick={() => setActiveIndex(index)}>
          ...
        </AccordionButton>
      </h2>
      <AccordionPanel pb={4} isOpen={index === activeIndex}>
        ...
      </AccordionPanel>
    </AccordionItem>
  );
};

CSS 隔离

最后,你可以使用 CSS 隔离来防止手风琴之间的交互。这可以通过使用唯一的选择器或命名空间来实现。

.accordion-container {
  display: flex;
  gap: 8%;
  flex-wrap: wrap;
}

.accordion-item {
  flex: 46%;
  border-top: 0;
  border-bottom: 1px solid black;
}

.accordion-panel {
  padding-bottom: 4rem;
}

其他注意事项

  • 确保 Accordion 组件的 allowMultiple 属性设置为 false,以防止同时扩展多个手风琴。
  • 为每个手风琴使用明确的索引。
  • 考虑使用过渡效果来平滑手风琴的展开和收起动画。

常见问题解答

问:为什么手风琴之间会有交互冲突?
答:这是因为默认情况下,没有明确定义手风琴的交互,导致展开一个手风琴会自动收起其他所有手风琴。

问:受控手风琴有什么好处?
答:受控手风琴允许你完全控制手风琴的状态,防止它们受到其他手风琴的影响。

问:Context API 在这个场景中如何发挥作用?
答:Context API 提供了一种在多个组件之间共享手风琴状态的方法,从而避免交互冲突。

问:CSS 隔离如何帮助解决此问题?
答:CSS 隔离使用唯一的选择器或命名空间,防止手风琴之间的样式冲突,确保它们独立操作。

问:在使用这些解决方案时需要注意什么?
答:确保 allowMultiple 属性设置为 false,使用明确的索引,并考虑添加过渡效果以改善用户体验。