Typescript:在类中初始化一个事件监听器

问题描述 投票:0回答:1

我正在使用Typescript反应构建一个Web应用程序。我正在尝试制作一个可以扩展点击的手风琴菜单,但它只响应第二次点击。我想这是因为它只在第一次点击后开始收听。

有没有办法让它从一开始就听?我尝试在构造函数中初始化事件侦听器,但它似乎没有工作。

这是我的班级:

class SelectionMenu extends React.Component {
    constructor(props: Readonly<{}>){
        super(props);
        this.listenForAccordion = this.listenForAccordion.bind(this);
    }

    // opens and closes the accordian menu 
    public listenForAccordion(): void {
        for (i = 0; i < acc.length; i++) {
            acc[i].addEventListener("click", function() {
                this.classList.toggle("active");
                var panel = this.nextElementSibling;
                if (panel.style.maxHeight){
                panel.style.maxHeight = null;
                } else {
                panel.style.maxHeight = panel.scrollHeight + "px";
                } 
            });
        }
    }

    public render() {
        return (
        <div className="App-selectionmenu">
            <button className="Accordion" onClick={this.listenForAccordion}>Section 1</button>
            <div className="Panel">
            <p>Lorem ipsum...</p>
            </div>

            <button className="Accordion" onClick={this.listenForAccordion}>Section 2</button>
            <div className="Panel">
            <p>Lorem ipsum...</p>
            </div>

            <button className="Accordion" onClick={this.listenForAccordion}>Section 3</button>
            <div className="Panel">
            <p>Lorem ipsum...</p>
            </div>

        </div>
        );
    }
}
reactjs typescript react-tsx
1个回答
1
投票

您可以将手风琴行信息保持在组件状态,并将行设置为active而不是手动操作DOM,而是在render方法中将该行设置为应用于该行的样式。

class SelectionMenu extends React.Component {
  state = {
    rows: [{ active: false }, { active: false }, { active: false }]
  };

  onClick = index => {
    this.setState(previousState => {
      const rows = [...previousState.rows];
      rows[index] = { ...rows[index], active: !rows[index].active };
      return { rows };
    });
  };

  render() {
    return (
      <div className="App-selectionmenu">
        {this.state.rows.map((row, index) => (
          <div key={index}>
            <button className="Accordion" onClick={() => this.onClick(index)}>
              Section 1
            </button>
            <div className="Panel">
              <p>Lorem ipsum... {row.active && " (Active!)"}</p>
            </div>
          </div>
        ))}
      </div>
    );
  }
}

ReactDOM.render(<SelectionMenu />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>
© www.soinside.com 2019 - 2024. All rights reserved.