0

In the image as you can see, I have a Foo page, where I have 10 Accordions, In one of the Accordions there is a Form component, When I submit the Form it calls a remote API and returns some JSON data, I convert it to a Table of content and want to show it under the Form.

The problem is I can show the Table after toggling the Accordion again after the submit button clicked, as I have set the maxheight in the onClick.

const [activeState, setActiveState] = useState("");
const [activeHeight, setActiveHeight] = useState("0px");

const toogleActive = () => {
    setActiveState(activeState === "" ? "active" : "");
    setActiveHeight(activeState === "active" ? "0px" :`${contentRef.current.scrollHeight}px`)
    }


return (
    <div className={styles.accordion_section}>
      <button className={styles.accordion} onClick={toogleActive}>
        <p className={styles.accordion_title}>{title}</p>
      </button>

      <div ref={contentRef}
        style={{ maxHeight: `${activeHeight}` }}
        className={styles.accordion_content}>
        <div>
          {content}
          </div>
      </div>
    </div>
  )

I have used context also to share the useState hook between Accordion and Form components to update the height.

  <UpdateHeightContext.Provider value={{updateHeight, setUpdateHeight}}>
      <Accordion title="Find your Data" content={< FormWithTwoInput firstLabel="FirstName" secondLabel="LastName" buttonColor="blue" buttonText="Check Deatils"/>} />
      </UpdateHeightContext.Provider>

Is there any way to update the Accordions height dynamically when I receive the response from the API? Other than toggling it again. A similar question was asked here React accordion, set dynamic height when DOM's children change unfortunately no one replied.

Accordion and form

Sumit Paul
  • 21
  • 7

1 Answers1

0

Even though the working around what I have found is not a robust one, but it is working completely fine for me. If someone stumbles upon this same issue might find this useful.

import React, { useState, useRef } from 'react'

const Accordion = ({ title, content }) => {

const [activeState, setActiveState] = useState("");
const [activeHeight, setActiveHeight] = useState("0px");
const contentRef = useRef("form")

const toogleActive = () => {
    setActiveState(activeState === "" ? "active" : "");
    setActiveHeight(activeState === "active" ? "0px" :`${contentRef.current.scrollHeight + 100}px`)
    }


return (
    <div className={styles.accordion_section}>
      <button className={styles.accordion} onClick={toogleActive}>
        <p className={styles.accordion_title}>{title}</p>
      </button>

      <div ref={contentRef}
        style={{ maxHeight: `${activeHeight}` }}
        className={styles.accordion_content}>
        <div>
          {content}
          </div>
      </div>
    </div>
  )
}

Accordion.propTypes = {
    title: PropTypes.string,
    content: PropTypes.object,
}

export default Accordion

I have hardcoded some extra space so that while the dynamic response is accepted the Table content is shown. In the CSS module file, I have kept the overflow as auto, earlier it was hidden.

  .accordion_content {
    background-color: white;
    overflow: auto;
    max-height: max-content;
  }

As a result, the Table is appearing dynamically and the user can scroll inside the Accordion if my Table needs larger space.

Sumit Paul
  • 21
  • 7