Javascript 展开/折叠所有数据

Javascript 展开/折叠所有数据,javascript,css,reactjs,accordion,collapse,Javascript,Css,Reactjs,Accordion,Collapse,我正在做一个手风琴,当我们点击每个单独的项目,然后它的开始或结束以及 现在我已经实现了expandall或collapseall选项,以使所有手风琴展开/折叠 Accordion.js const accordionArray = [ { heading: "Heading 1", text: "Text for Heading 1" }, { heading: "Heading 2", text: "Te

我正在做一个手风琴,当我们点击每个单独的项目,然后它的开始或结束以及

现在我已经实现了expandall或collapseall选项,以使所有手风琴展开/折叠

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>
      ))}
要求:

如果单击“全部展开/全部折叠”按钮,则应分别打开/关闭所有手风琴

无论以前打开/关闭的手风琴如何,这都应起作用。。因此,如果“全部展开”,则应打开所有手风琴,否则需要关闭所有手风琴,即使之前已打开/关闭

链接:

这是道具实际传递到的文件的链接

编辑:

如果我使用
{this.props.children}
那么每个手风琴都会打开。。没有问题


但是,如果我在单击特定项目时手动打开任何手风琴,那么如果我单击“全部展开”,则其已展开(预期),但如果我单击“全部折叠”选项,则不是所有手风琴都关闭。。我们之前打开的那些仍处于打开状态。。但此处的预期行为是所有内容都应关闭。

在这种情况下,this.props.render不是函数,this.props.text未定义,请尝试替换此行

  <div className={`content open`}>
    {this.props.render && this.props.render(this.props.text)}
  </div>

{this.props.render&&this.props.render(this.props.text)}
据此:

  <div className={`content open`}>
   {this.props.children}
  </div>

{this.props.children}
编辑:// 另一种解决方案是将expandAll属性传递给Accordion组件

  <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>

{项目标题}

{item.text}

然后在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>;
    }
  };
onShow=(i)=>{
这是我的国家({
主动:这个。道具。全部?-1:i,
预备队:这个。道具。全部?-1:我
});
if(this.state.reserve==i){
这是我的国家({
主动:-1,
储备:-1
});
}
};
render(){
const children=React.children.map(this.props.children,(child,i)=>{
返回React.cloneElement(子级{
标题:this.props.expandAll | | this.state.active==i,
text:this.props.expandAll | | this.state.active+stage==i,
onShow:()=>这个.onShow(i)
});
});
返回{children};
}
};
在您的text.js文件中

在第9行。请将以前的代码替换为:
{this.props.children}

在沙箱里试过,为我工作

/// 无法添加注释,因此无法编辑答案本身。 accorbian.js包含您的hook expandAll,标题boolean已经出现在getaccorbian.js中。
我建议将expand all移动到getaccorbian.js,以便您可以控制这两个值。

基于@lissettdm answer,我不清楚为什么
getAccordion
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>
      ))}
    </>
  );
};
const NormalAccordion=()=>{
const accordionArray=[/…您的数据];
常量[状态,设置状态]=使用状态({
全部:错,
…accordiogray.map(项=>false),
});
常量handleExpandAll=()=>{
设置状态((prevState)=>({
expandAll:!prevState.expandAll,
…accordiogray.map(项=>!prevState.expandAll),
}));
};
const handlettextexpand=(id)=>{
设置状态((prevState)=>({
…国家,
[id]:!prevState[id]
}));
};
返回(
{state.expandAll?`Collapse All`:`Expand All`}

{accordiogray.map((项目,索引)=>( {项目标题}

{item.text}

))} ); };
Heading返回索引,以便父组件知道要关闭哪个项

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>
    );
  }
}
类标题扩展了React.Component{
handleExpand=()=>{
this.props.handletexpand(this.props.id);
};
render(){
返回(
{this.props.children}
);
}
}
文本只关心一个道具,以确定它是否应该显示展开内容

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>
    );
  }
}
类文本扩展React.Component{
render(){
返回(
{this.props.shouldExpand?this.props.children:}
);
}
}

谢谢您的回答。。但在这里,如果我点击标题2,点击“全部展开”,那么所有内容都会被打开,这样就可以了。。但是,如果我使全部折叠,标题2仍然打开,而它应该折叠全部手风琴。同样,如果我手动打开全部手风琴并单击“展开全部”,则不会发生任何情况(预期)。但如果我再次单击“全部折叠”,则没有手风琴关闭,所有内容仍然打开。。那么,你能帮我修复手动打开和折叠所有内容的问题吗?再次感谢,我已经通过getAccordion.js中的
componentDidUpdate
mentod实现了这一点,就像这里通过将道具传递给Accordion一样。但是我已经在这里实现了你的解决方案,如果我们扩展,还有一个问题所有的手风琴,然后它是不可能关闭手动点击任何特定的手风琴。是的,你的解决方案看起来更好;)谢谢你的回答。。但在这里,如果我点击标题2,点击“全部展开”,那么所有内容都会被打开,这样就可以了。。但是,如果我使全部折叠,标题2仍然打开,而它应该折叠全部手风琴。同样,如果我手动打开全部手风琴并单击“展开全部无任何内容”
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>
    );
  }
}