Home > Mobile >  Why the Accordion in my react app is not working as I want it to be
Why the Accordion in my react app is not working as I want it to be

Time:10-26

I'm facing some issues with my React application.

First I will explain what I want in my app then I will talk about the issues.

I have a list of 6 Services and I want to wrap each service list in Accordion. Whenever the user clicks the " " button for the specific service I want that list to be displayed with slides down with a growing margin-bottom, depending on the number of items in the respective list without overlapping the below element.

While trying to achieve this, I'm facing the following issues.

1- when I click " " button it toggles all 6 services and their list items are getting displayed.

2- all list items overlapping the below elements. enter image description here

I tried with useState()

const [showServices, setShowServices] = useState(false);
  const toggle = () =>{    
   setShowServices((prevState) => !prevState);
}

<div className="services__service__description">
  <h4 className="title">Services</h4>
  <span style={{cursor: 'pointer', fontSize: '20px', fontWeight: 'bold'}} id='showBtn' 
    onClick={toggle}> </span>
  <div className="accordion">
    {text.map((t) => (                    
      <div className="content" id='services'>
         <div id='srvs' key={t.id}>
            {showServices ? t.info : ''}
         </div>
      </div>                                        
    ))}
   </div>
</div>

Edit cool-estrela-hf7plv

CodePudding user response:

As I guss from part of your code, you binded single state to all Service related info.

The state showServices is shared between all item and when it changed from one item, then affect all other items.

Define new child component for info like example that i prepare for you.

function ServiceDetail({ service }) {
    const [show, setShow] = React.useState(false);
    function toggle() {
        setShow(s => !s);
    }

 return   <div className="detail">
        <h4 className="title">{service.name}</h4>
        <span style={{ cursor: 'pointer', fontSize: '20px', fontWeight: 'bold' }} id='showBtn'
            onClick={toggle}> </span>
        <div className="accordion">
            {service.detail.map((t, index) => (
                <div  key={index} className="content" id='services'>
                    <div id='srvs'>
                        {show ? t : ''}
                    </div>
                </div>
            ))}
        </div>
    </div>
}

function Service() {
    const [services, setServices] = React.useState(
        [
            {
                id: 1,
                name: "Service 1",
                detail: ["list-1","list-2","list-3"]
            },
            {
                id: 2,
                name: "Service 2",
                detail: ["bb"]
            },
            {
                id: 3,
                name: "Service 3",
                detail: ["bb"]
            },
            {
                id: 4,
                name: "Service 4",
                detail: ["bb"]
            },
            {
                id: 5,
                name: "Service 5",
                detail: ["bb"]
            }
        ]
    );
    return <div className="service">
        {
            services.map((service) => {
                return <ServiceDetail key={service.id} service={service} />
            })
        }
    </div>
}



function App() {
    return <Service />;
}

ReactDOM.render(< App className="app" />, document.getElementById("root"));
.app{
width:100%;
}
.service{
display:grid;
column-gap: 1rem;
align-items:flex-start;
align-content:flex-start;
row-gap: 2rem;
grid-template-columns: 1fr 1fr 1fr;
}
.detail{
color:#9c772d;
background:#eeeeee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

Edit: For size problem, just you need to add following css to container as i add to sample:

align-items:flex-start;
align-content:flex-start;
  • Related