简体   繁体   中英

I'm trying to make a collapse/accordion in React. But the problem is, it is not triggering the specific content that i want to toggle

I'm trying to make a collapse/accordion in React. But the problem is, it is not triggering the specific content that I want to toggle ie when I click on the heading, all of the paragraph tags achieved maximum height. I know there is no error in this code but I also don't know that how to trigger a specific paragraph tag.

Here is my React code:

import React, {useState} from 'react'
import style from './stylecss.module.css'
import AnimateHeight from 'react-animate-height'
import cx from 'classname'
import globalStyles from '../Assets/global-styles/bootstrap.module.css'

function Collapse() {

  const item = [
    {
      heading : "HEADING 1",
      para : "DATA 1"
    },
    {
      heading : "HEADING 2",
      para : "DATA 2"
    }
  ]
  
  const [state, setState] = useState("0")
  
  function displayPara (){
    console.log(itemPlace)
    if(state==0)
      setState("auto")
    else
      setState(0)
  }

  const itemPlace = item.map(({heading, para}) => {
    return (
    <div>
      <h5 onClick={ e => displayPara()}>
        {heading}
      </h5>
      <AnimateHeight duration={ 500 } height={ `${state}` }>
        <p>{para}</p>
      </AnimateHeight>
    </div>
    )
  })
  return (
    <div className={style.AboutPage}>
      {itemPlace}
    </div>
  )
}

export default Collapse

This is CSS code


.AboutPage {
    margin-top : 40px;
    padding : 30px 6% 10px 6%;
    background-color: rgb(250, 250, 250);
    display: flex;
    flex-direction: column;
    text-align: left;
}
.paraDiv {
    color : red !important;
    width: 100%;
    height : 100%;
    background-color: chartreuse;
    transition: max-height 0.5s;
}

.paraDiv.is-active {
    height: 300px;
}

I would prefer not to use built-in or pre-defined Collapse Components.

You can do it natively.

 <details> <summary>Epcot Center</summary> <p>Epcot is a theme park at Walt Disney World Resort featuring exciting attractions, international pavilions, award-winning fireworks and seasonal special events.</p> </details>

Quick Reminder that Details/Summary is the Easiest Way Ever to Make an Accordion

First of all good luck!

What your code saying is: When user click one of the items (specifically the h5 tag), set the height to auto. and you give this height to every item, with no distinction if it's the one that should be open or not.

So what you want to do is to apply the height you changed in the 'state' property only to the item the user clicked on.

I've added a couple lines of code to make it.

  1. Add another state property, called activeItem which indicates which are the active item (the one that the user clicked on).
  2. Add a parameter to the displayPara function: the active index we want to display.
  3. Only apply the height we set in the function to the activeItem .

You can see it here.

 import React, {useState} from 'react' import style from './stylecss.module.css' import AnimateHeight from 'react-animate-height' import cx from 'classname' import globalStyles from '../Assets/globalstyles/bootstrap.module.css' function Collapse() { const item = [ { heading: "HEADING 1", para: "DATA 1" }, { heading: "HEADING 2", para: "DATA 2" } ] const [state, setState] = useState("0") const [activeItem, setActiveItem] = useState(null) function displayPara (index){ console.log(itemPlace) setActiveItem(index) if(state==0) setState("auto") else setState(0) } const itemPlace = item.map(({heading, para}, index) => { return ( <div> <h5 onClick={ e => displayPara(index)}> {heading} </h5> <AnimateHeight duration={ 500 } height={ `${activeItem === index? state: 0}` }> <p>{para}</p> </AnimateHeight> </div> ) }) return ( <div className={style.AboutPage}> {itemPlace} </div> ) } export default Collapse

As one of the comments above says, you can also achieve it natively without holding any state, using the details and summary HTML tags. You can also style it to be exactly like in your design with CSS.

 <details> <summary>Heading 1</summary> <p>Heading 1 Content</p> </details>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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