ReactJS 功能组件:手风琴,允许使用 useState 多选打开
ReactJS Function Component: accordion, allow for multiple selected open with useState
我在 ReactJS 中模拟了手风琴可折叠面板的简单逻辑。我正在尝试允许打开多个可折叠项,但无论单击哪个可折叠项,我都无法避免同时打开和关闭所有可折叠项。下面是手风琴一次只允许折叠一个的逻辑。
//Accordion.js
import React, { useState } from "react";
import styled, { css } from "styled-components";
import PropTypes from "prop-types";
import Collapse from "./Collapse";
import Header from "./Header";
const Accordion = ({ list, icon}) => {
const [isActiveIndex, setActiveIndex] = useState(null);
const toggleItem = index => {
setActiveIndex(isActiveIndex === index ? null : index);
};
return (
<Wrapper>
{list.map((item, index) => {
const checkOpen = isActiveIndex === index;
return (
<Container key={index}>
<Header
title={item.title}
icon={icon}
id={index}
onClick={toggleItem}
/>
<Body isOpen={checkOpen}>
<Collapse isOpen={checkOpen}>{item.content}</Collapse>
</Body>
</Container>
);
})}
</Wrapper>
);
};
我在此处的 CodeSandBox 中创建了整个模拟:https://codesandbox.io/s/1r2mvk87q
对于初始手风琴,我正在使用 useState
并检查活动索引 - 对于 allow multiple 我想我应该检查被点击项目的先前状态,但我无法通过单击项目作为要检查状态的唯一目标。
//AccordionMultiple.js
const AccordionM = ({ list, icon }) => {
const [isOpen, setOpen] = useState(false);
const toggleItemM = index => {
setOpen(prevState => !prevState);
};
return (
<Wrapper>
{list.map((item, index) => {
return (
<Container key={index}>
<Header
title={item.title}
icon={icon}
id={index}
onClick={toggleItemM}
/>
<Body isOpen={isOpen}>
<Collapse isOpen={isOpen}>{item.content}</Collapse>
</Body>
</Container>
);
})}
</Wrapper>
);
};
为了允许多个可折叠列,您可以使用对象而不是单个索引
const Accordion = ({ list, icon}) => {
const [isActivePanel, setActivePanel] = useState({});
const toggleItem = index => {
setActivePanel(prevState => ({...prevState, [index]: !Boolean(prevState[index])}));
};
return (
<Wrapper>
{list.map((item, index) => {
const checkOpen = isActivePanel[index];
return (
<Container key={index}>
<Header
title={item.title}
icon={icon}
id={index}
onClick={toggleItem}
/>
<Body isOpen={checkOpen}>
<Collapse isOpen={checkOpen}>{item.content}</Collapse>
</Body>
</Container>
);
})}
</Wrapper>
);
};
我在 ReactJS 中模拟了手风琴可折叠面板的简单逻辑。我正在尝试允许打开多个可折叠项,但无论单击哪个可折叠项,我都无法避免同时打开和关闭所有可折叠项。下面是手风琴一次只允许折叠一个的逻辑。
//Accordion.js
import React, { useState } from "react";
import styled, { css } from "styled-components";
import PropTypes from "prop-types";
import Collapse from "./Collapse";
import Header from "./Header";
const Accordion = ({ list, icon}) => {
const [isActiveIndex, setActiveIndex] = useState(null);
const toggleItem = index => {
setActiveIndex(isActiveIndex === index ? null : index);
};
return (
<Wrapper>
{list.map((item, index) => {
const checkOpen = isActiveIndex === index;
return (
<Container key={index}>
<Header
title={item.title}
icon={icon}
id={index}
onClick={toggleItem}
/>
<Body isOpen={checkOpen}>
<Collapse isOpen={checkOpen}>{item.content}</Collapse>
</Body>
</Container>
);
})}
</Wrapper>
);
};
我在此处的 CodeSandBox 中创建了整个模拟:https://codesandbox.io/s/1r2mvk87q
对于初始手风琴,我正在使用 useState
并检查活动索引 - 对于 allow multiple 我想我应该检查被点击项目的先前状态,但我无法通过单击项目作为要检查状态的唯一目标。
//AccordionMultiple.js
const AccordionM = ({ list, icon }) => {
const [isOpen, setOpen] = useState(false);
const toggleItemM = index => {
setOpen(prevState => !prevState);
};
return (
<Wrapper>
{list.map((item, index) => {
return (
<Container key={index}>
<Header
title={item.title}
icon={icon}
id={index}
onClick={toggleItemM}
/>
<Body isOpen={isOpen}>
<Collapse isOpen={isOpen}>{item.content}</Collapse>
</Body>
</Container>
);
})}
</Wrapper>
);
};
为了允许多个可折叠列,您可以使用对象而不是单个索引
const Accordion = ({ list, icon}) => {
const [isActivePanel, setActivePanel] = useState({});
const toggleItem = index => {
setActivePanel(prevState => ({...prevState, [index]: !Boolean(prevState[index])}));
};
return (
<Wrapper>
{list.map((item, index) => {
const checkOpen = isActivePanel[index];
return (
<Container key={index}>
<Header
title={item.title}
icon={icon}
id={index}
onClick={toggleItem}
/>
<Body isOpen={checkOpen}>
<Collapse isOpen={checkOpen}>{item.content}</Collapse>
</Body>
</Container>
);
})}
</Wrapper>
);
};