如何使用 React Hooks 单独切换手风琴面板?
How can I toggle accordion panels individually using React Hooks?
目前,所有手风琴面板正在同时切换。我试过将索引传递给点击处理程序,但没有成功。如何将当前索引与当前 setActive 变量进行比较以单独打开和关闭手风琴面板?我在生产中使用的数据没有唯一的 ID,这就是我使用 index.html 的原因。感谢您的任何建议!
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.scrollHeight}px`
);
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>
);
};
您的代码中的问题是您正在生成一个通用的 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.scrollHeight}px`}` }}
className="accordion__content">
<div>{item.content}</div>
</div>
</div>
)})}
</div>
);
};
想法是,对于循环中的每个项目,您找到哪个处于活动状态,然后根据此分配 类 / 样式。可以进行更多的重构,但现在我让你清理一下,因为这个想法应该在那里 :)
目前,所有手风琴面板正在同时切换。我试过将索引传递给点击处理程序,但没有成功。如何将当前索引与当前 setActive 变量进行比较以单独打开和关闭手风琴面板?我在生产中使用的数据没有唯一的 ID,这就是我使用 index.html 的原因。感谢您的任何建议!
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.scrollHeight}px`
);
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>
);
};
您的代码中的问题是您正在生成一个通用的 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.scrollHeight}px`}` }}
className="accordion__content">
<div>{item.content}</div>
</div>
</div>
)})}
</div>
);
};
想法是,对于循环中的每个项目,您找到哪个处于活动状态,然后根据此分配 类 / 样式。可以进行更多的重构,但现在我让你清理一下,因为这个想法应该在那里 :)