【问题标题】:Typescript: initialize an event listener within a class打字稿:在类中初始化事件侦听器
【发布时间】:2018-11-02 20:29:45
【问题描述】:

我正在使用 Typescript react 构建一个 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】:

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

    示例

    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>

    【讨论】:

      猜你喜欢
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 2021-05-18
      • 2020-05-08
      • 1970-01-01
      • 2018-06-01
      • 1970-01-01
      相关资源
      最近更新 更多