简体   繁体   English

ReactJs Accordion 自动关闭机制

[英]ReactJs Accordion Automatic Close Mechanism

I'm currently working on an accordion component in react version 16.3.2, that receives props from another component and displays the accordion accordingly.我目前正在研究版本 16.3.2 中的手风琴组件,该组件从另一个组件接收道具并相应地显示手风琴。 Unfortunately I cannot use hooks.不幸的是我不能使用钩子。

This works pretty smoothly, what I want to implement now is a way so that only one accordion can be opened at the same time on the same page.这很顺利,我现在想要实现的是一种方法,以便在同一页面上只能同时打开一个手风琴。 So, once you open one accordion (while another is already opened) it should automatically close the already opened one.因此,一旦您打开一个手风琴(而另一个已经打开),它应该会自动关闭已经打开的手风琴。

I have an Id (string which describes the current section, eg 'contact', 'info', etc.) and the state of an accordion gets saved in the state (set to true when you toggle the accordion).我有一个 Id(描述当前部分的字符串,例如“联系人”、“信息”等)并且手风琴的状态保存在该状态中(当您切换手风琴时设置为 true)。 I'm not quite sure on how I could implement this mechanism and am looking for tips on how I could solve this in a smart way.我不太确定如何实现这种机制,正在寻找有关如何以智能方式解决此问题的提示。 Any pointers?任何指针?

example: https://codesandbox.io/s/reactjs-accordion-automatic-close-mechanism-6dys1 (I didn't add all of the styling, animations since this is more about functionality)示例: https : //codesandbox.io/s/reactjs-accordion-automatic-close-mechanism-6dys1 (我没有添加所有样式和动画,因为这更多的是关于功能)

You can find solution for your problem in the following codesandbox https://codesandbox.io/s/reactjs-accordion-automatic-close-mechanism-yejc0您可以在以下代码和框中找到问题的解决方案https://codesandbox.io/s/reactjs-accordion-automatic-close-mechanism-yejc0

Change prop names as it fits your code base, but the logic is solid更改适合您的代码库的道具名称,但逻辑是可靠的

You could do something like this, using the state hook in the App component您可以使用 App 组件中的状态钩子来做这样的事情

export default function App() {
  const items = [
    { id: 1, title: 'First Accordion', content: 'Hello' },
    { id: 2, title: 'Click me', content: 'Hello 2' },
    { id: 3, title: 'Third Accordion Accordion', content: 'Hello 3' },
  ]

  const [selectedItem, setSelectedItem] = useState(1)

  const handleClick = id => {
    setSelectedItem(id)
  }
  return (
    <div className="App">
      {items.map(x => {
        return (
          <Accordion 
            key={x.id} 
            id={x.id}
            title={x.title} 
            open={x.id === selectedItem}
           onClick={handleClick}
          >
            <p>{x.title}</p>
          </Accordion>
        )
      })}
    </div>
  );
}

Then your accordion component is a bit simpler那么你的手风琴组件就简单一点

class Accordion extends React.Component {
  accToggle() {
    this.props.onClick(this.props.id);
  }

  sectionClasses() {
    let classes = "accordion";
    classes += this.props.open ? " sec-on" : "";
    classes += "sec-underway";

    return classes.trim();
  }

  render() {
    return (
      <section className={this.sectionClasses()} id={this.props.id}>
        <div className="acc-title" onClick={this.accToggle.bind(this)}>
          <h3 className="acc-text">{this.props.title}</h3>
          <div className="acc-nav">
            <span className="acc-toggle" />
          </div>
        </div>

        <div className="acc-content">{this.props.children}</div>
      </section>
    );
  }
}

Accordion.defaultProps = {
  open: false
};

Accordion.propTypes = {
  id: PropTypes.number.isRequired,
  children: PropTypes.any,
  onFocus: PropTypes.func,
  progress: PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.string,
    PropTypes.bool
  ]),
  title: PropTypes.string,
  open: PropTypes.bool
};

export default Accordion;

The accordion calls a function on the app component, which updates the state and the display logic is passed down in the props手风琴调用app组件上的一个函数,更新状态,显示逻辑在props中传递

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM