【问题标题】:How to.close accordion when clicked for the second time?第二次点击时如何关闭手风琴?
【发布时间】:2020-10-04 11:21:22
【问题描述】:


import React, { useState } from 'react';

const Accordion = ({ items }) => {
    const [activeIndex, setActiveIndex] = useState(null);

    const onTitleClick = (index) => {
        setActiveIndex(index);
    };

    const renderedItems = items.map((item, index) => {
        const active = index === activeIndex ? 'active' : '';

        return (
            <React.Fragment key={item.title}>
                <div className={`title ${active}`} onClick={() => onTitleClick(index)}>
                    <i className='dropdown icon'></i>
                    {item.title}
                </div>
                <div className={`content ${active}`}>
                    <p>{item.content}</p>
                </div>
            </React.Fragment>
        );
    });
    return <div className='ui styled accordion'>{renderedItems}</div>;
};

export default Accordion;

我使用语义 UI 库创建了一个手风琴。 我能够将下拉菜单类设置为“活动”,因此我点击的任何内容都会展开。

我正在尝试对以下代码实现“第二次点击关闭”功能, 所以我尝试通过在 onTitleClick 函数下添加以下代码来实现:

    const onTitleClick = (index) => {
        if (index === activeIndex) {
            setActiveIndex(null); // in case 'clicked index' is the same as what's active, then configure it to "null" and rerender 
        }
        setActiveIndex(index);
    };

我的理解是每当状态更新时,react 都会再次运行它的脚本,所以在这种特殊情况下,如果单击相同的索引,变量“active”应该返回空字符串。

第二次点击的时候,出乎我的意料,什么也没发生。

我尝试在if语句中console.log,它会显示我已经第二次点击了该项目。

请指教。

【问题讨论】:

    标签: javascript reactjs user-interface


    【解决方案1】:

    问题就在这里:

    const onTitleClick = (index) => {
            if (index === activeIndex) {
                setActiveIndex(null); // in case 'clicked index' is the same as what's active, then configure it to "null" and rerender 
            }
            setActiveIndex(index); <-- here
        }
    

    这里发生的情况是,如果if 条件匹配,则它设置为setActiveIndex null 但代码将再次运行,因此它再次设置为setActiveIndex(index)。这就是为什么单击不起作用的原因。你需要这样做:

     const onTitleClick = (index) => {
        if (activeIndex === index) {
          setActiveIndex(null);
        } else {
          setActiveIndex(index);
        }
      };
    
    

    这里是演示:https://codesandbox.io/s/musing-poitras-bkiwh?file=/src/App.js:270-418

    【讨论】:

    • 非常感谢......哇......这只是一个逻辑。
    • 如果这适用于将此答案标记为已接受,那就太好了。以至于以后有人卡住了。他们可以看到这个答案
    【解决方案2】:

    试试下面的方法,

     const onTitleClick = (index) => {
          setActiveIndex(activeIndex !== index ? index : null);
      };
    

    【讨论】:

      【解决方案3】:

      我已经尝试过使用 react 类组件,所以成功了。

      import React, { Component } from 'react';
      
      class Accordion extends Component {
        state = {
          activeIndex: null
        }
        onTitleClick = (index) => event => {
          const { activeIndex } = this.state;
          this.setState({ activeIndex: activeIndex == index ? null : index })
        };
      
      
        render() {
          const { activeIndex } = this.state;
          const{items}=this.props;
          return <div className='ui styled accordion'>
            {
              items.map((item, index) => {
                const active = index === activeIndex ? 'active' : '';
                return <React.Fragment key={item.title}>
                  <div className={`title ${active}`} onClick={this.onTitleClick(index)}>
                    <i className='dropdown icon'></i>
                    {item.title}
                  </div>
                  <div className={`content ${active}`}>
                    <p>{item.content}</p>
                  </div>
                </React.Fragment>
              })
            }
          </div>
        }
      }
      
      export default Accordion;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-16
        • 1970-01-01
        • 1970-01-01
        • 2017-10-26
        • 1970-01-01
        • 1970-01-01
        • 2015-02-17
        • 1970-01-01
        相关资源
        最近更新 更多