如何解决展开/折叠所有数据
我正在制作手风琴,当我们单击每个单独的项目时,它的打开或关闭状态都很好。
现在我已经实现了全部展开或全部折叠的选项,以使所有手风琴展开/折叠。
Accordion.js
const accordionArray = [
{ heading: "heading 1",text: "Text for heading 1" },{ heading: "heading 2",text: "Text for heading 2" },{ heading: "heading 3",text: "Text for heading 3" }
];
.
.
.
{accordionArray.map((item,index) => (
<div key={index}>
<Accordion>
<heading>
<div className="heading-Box">
<h1 className="heading">{item.heading}</h1>
</div>
</heading>
<Text expandAll={expandAll}>
<p className="text">{item.text}</p>
</Text>
</Accordion>
</div>
))}
text.js 是一个文件,在该文件中,我将按照以下步骤打开手风琴的任何特定内容和代码,
import React from "react";
class Text extends React.Component {
render() {
return (
<div style={{ ...this.props.style }}>
{this.props.expandAll ? (
<div className={`content open`}>
{this.props.render && this.props.render(this.props.text)}
</div>
) : (
<div className={`content ${this.props.text ? "open" : ""}`}>
{this.props.text ? this.props.children : ""}
{this.props.text
? this.props.render && this.props.render(this.props.text)
: ""}
</div>
)}
</div>
);
}
}
export default Text;
在这里通过this.props.expandAll
得到的值,无论expandAll是true还是false。如果为真,则所有手风琴都将获得类className={`content open`}
,因此所有手风琴都将打开。
问题:
应用open
类,但不呈现内部文本内容。
所以这行不起作用
{this.props.render && this.props.render(this.props.text)}
要求:
如果单击全部展开/全部折叠按钮,则应分别打开/关闭所有手风琴。
这应该与以前打开/关闭的手风琴无关。。因此,如果全部展开,则应该打开所有手风琴,或者即使先前已打开/关闭它也要关闭所有手风琴。 / p>
链接:
这是文件https://codesandbox.io/s/react-accordion-forked-sm5fw?file=/src/GetAccordion.js的链接,实际上是道具的传递对象。
编辑:
如果我使用{this.props.children}
,那么每个手风琴都会打开。.没有问题。
但是,如果我在单击特定项目时手动打开任何手风琴,则如果我单击全部展开,则其展开(预期),但是如果我单击返回全部折叠选项,则不是全部将关闭。我们以前打开的那些仍然处于打开状态。但是,这里的预期行为是所有内容都应该关闭。
解决方法
在这种情况下,this.props.render不是函数,并且this.props.text是未定义的,请尝试替换此行
<div className={`content open`}>
{this.props.render && this.props.render(this.props.text)}
</div>
由此:
<div className={`content open`}>
{this.props.children}
</div>
编辑:// 其他解决方案是将expandAll属性传递给“手风琴”组件
<Accordion expandAll={expandAll}>
<Heading>
<div className="heading-box">
<h1 className="heading">{item.heading}</h1>
</div>
</Heading>
<Text>
<p className="text">{item.text}</p>
</Text>
</Accordion>
然后在getAccordion.js
onShow = (i) => {
this.setState({
active: this.props.expandAll ? -1: i,reserve: this.props.expandAll ? -1: i
});
if (this.state.reserve === i) {
this.setState({
active: -1,reserve: -1
});
}
};
render() {
const children = React.Children.map(this.props.children,(child,i) => {
return React.cloneElement(child,{
heading: this.props.expandAll || this.state.active === i,text: this.props.expandAll || this.state.active + stage === i,onShow: () => this.onShow(i)
});
});
return <div className="accordion">{children}</div>;
}
};
,
在文件text.js中
第9行,请用以下代码替换之前的代码:
{this.props.children}
在沙盒中尝试过,为我工作。
/// 无法添加评论,因此只能编辑答案。 Accordian.js包含您的钩子expandAll,标题布尔值已经在GetAccordian.js中了。 我建议将全部展开移动到GetAccordian.js,以便您可以控制两个值。
,在@lissettdm答案的基础上,我不清楚为什么getAccordion
和accordion
是两个单独的实体。您可能有很充分的理由进行分离,但是两个组件的状态是相互依存的事实表明,将它们更好地实现为一个组件。
Accordion现在像以前一样直接控制其子级的状态,但不使用getAccordion。现在,切换expandAll也会重置各个项目的状态。
const NormalAccordion = () => {
const accordionArray = [ //... your data ];
const [state,setState] = useState({
expandAll: false,...accordionArray.map(item => false),});
const handleExpandAll = () => {
setState((prevState) => ({
expandAll: !prevState.expandAll,...accordionArray.map(item => !prevState.expandAll),}));
};
const handleTextExpand = (id) => {
setState((prevState) => ({
...prevState,[id]: !prevState[id]
}));
};
return (
<>
<div className="w-full text-right">
<button onClick={handleExpandAll}>
{state.expandAll ? `Collapse All` : `Expand All`}
</button>
</div>
<br />
{accordionArray.map((item,index) => (
<div key={index}>
<div className="accordion">
<Heading handleTextExpand={handleTextExpand} id={index}>
<div className="heading-box">
<h1 className="heading">{item.heading}</h1>
</div>
</Heading>
<Text shouldExpand={state[index]}>
<p className="text">{item.text}</p>
</Text>
</div>
</div>
))}
</>
);
};
标题将索引传回,以便父组件知道要关闭的项目。
class Heading extends React.Component {
handleExpand = () => {
this.props.handleTextExpand(this.props.id);
};
render() {
return (
<div
style={ //... your styles}
onClick={this.handleExpand}
>
{this.props.children}
</div>
);
}
}
文本仅关心一个道具来确定是否应显示展开内容。
class Text extends React.Component {
render() {
return (
<div style={{ ...this.props.style }}>
<div
className={`content ${this.props.shouldExpand ? "open" : ""}`}
>
{this.props.shouldExpand ? this.props.children : ""}
</div>
</div>
);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。