如何使用 React Hooks 单独切换手风琴面板?
Posted
技术标签:
【中文标题】如何使用 React Hooks 单独切换手风琴面板?【英文标题】:How can I toggle accordion panels individually using React Hooks? 【发布时间】:2021-12-13 08:34:06 【问题描述】:目前,所有手风琴面板都在同时切换。我试过将索引传递给点击处理程序,但没有运气。如何将当前索引与当前 setActive 变量进行比较以单独打开和关闭手风琴面板?我在生产中使用的数据没有唯一的 id,这就是我使用 index.html 的原因。感谢您的任何建议!
演示:https://codesandbox.io/s/react-accordion-using-react-hooks-forked-fup4w?file=/components/Accordion.js:141-1323
const Accordion = (props) =>
const [setActive, setActiveState] = useState(0);
const [setHeight, setHeightState] = useState("0px");
const [setRotate, setRotateState] = useState("accordion__icon");
const content = useRef(null);
const toggleAccordion = (index) =>
setActiveState(setActive === index ? "active" : "");
setHeightState(
setActive === "active" ? "0px" : `$content.current.scrollHeightpx`
);
setRotateState(
setActive === "active" ? "accordion__icon" : "accordion__icon rotate"
);
return (
<div>
data.map((item, index) => (
<div key=index className="accordion__section">
<button
className=`accordion $setActive`
onClick=() => toggleAccordion(index)
>
<p className="accordion__title">item.title</p>
<Chevron className=`$setRotate` width=10 fill="#777" />
</button>
<div
ref=content
style= maxHeight: `$setHeight`
className="accordion__content"
>
<div>item.content</div>
</div>
</div>
))
</div>
);
;
【问题讨论】:
【参考方案1】:您的代码中的问题是您正在生成一个通用的 setActive 状态,然后将其传递给您的地图函数中的所有项目。您必须更改状态管理才能找到每个项目是否处于活动状态。 我会修改你的组件:
const Accordion = (props) =>
const [activeIndex, setActiveIndex] = useState(0);
const content = useRef(null);
return (
<div>
data.map((item, index) =>
const isActive = index === activeIndex
return (
<div key=index className="accordion__section">
<button
className=`accordion $isActive ? "active" : ""`
onClick=() => setActiveIndex(index)>
<p className="accordion__title">item.title</p>
<Chevron className=`$isActive ? "accordion__icon" : "accordion__icon rotate" ` width=10 fill="#777" />
</button>
<div
ref=content
style= maxHeight: `$isActive ? "0px" : `$content.current.scrollHeightpx``
className="accordion__content">
<div>item.content</div>
</div>
</div>
))
</div>
);
;
这个想法是,对于循环中的每个项目,您可以找到哪个 on 处于活动状态,然后根据此分配类/样式。可以进行更多重构,但现在我让你清理一下,因为这个想法应该存在:)
【讨论】:
感谢您的帮助!这绝对是正确的想法。我收到一个错误 TypeError: Cannot read property 'scrollHeight' of null 问题是您在元素的映射(循环)中分配了一个应该是唯一的 ref,因此每个元素都将自己分配给 ref 并且无法正常工作:) .我邀请您检查这个问题,该问题可能应该解决它并且与您的第一个问题没有直接关系:***.com/questions/52448143/…以上是关于如何使用 React Hooks 单独切换手风琴面板?的主要内容,如果未能解决你的问题,请参考以下文章