skip to Main Content

I want to have 4 buttons which unfold 4 divs onclick and it should only be possible for one div to be open. Therefore I created an Array with all buttons and gave everyone a false state. In my opinion everything should work well and when I refresh the website I don’t understand why all divs are first opened and if I click on a random of the 4 buttons every div closes and if I click it again nothing happens anymore. For more informations please ask.
Thank youenter image description here enter image description here

import React, { useState, useEffect } from "react";
import {
  facebookIcon,
  foursquareIcon,
  instagramIcon,
  lvLogo,
  pinterestIcon,
  plusIcon,
  snapchatIcon,
  twitterIcon,
  youtubeIcon,
} from "../utils";

const FooterTop = () => {
  const collapseList = document.querySelectorAll(".collapseable");
  console.log(collapseList);

  const [collapseStatesActive, setCollapseStatesActive] = useState(() =>
    Array.from({ length: collapseList.length }, () => false)
  );

  useEffect(() => {
    collapseList.forEach((item, index) => {
      if (collapseStatesActive[index]) {
        item.style.height = item.scrollHeight + "px";
        console.log("rolled out");
      } else {
        item.style.height = "0px";
        console.log("rolled in");
      }
    });
  }, [collapseStatesActive, collapseList]);

  const handleCollapse = (index) => {
    const newCollapseStates = collapseStatesActive.map((state, i) =>
      i === index ? !state : state
    );
    setCollapseStatesActive(newCollapseStates);
  };

  return (
    <>
      <div className="border-b">
        <div className="mt-8 flex justify-center">
          <img width={200} src={lvLogo} alt="LV Logo" />
        </div>
        <div className="mt-8">
          <div className="block border-t mx-5 py-4">
            <button
              onClick={() => handleCollapse(0)}
              className="flex items-center justify-between w-full"
            >
              <div>Wünschen Sie Beratung?</div>
              <img width={10} src={plusIcon} alt="add" />
            </button>
            <div
              id="collapse1"
              className="collapseable overflow-hidden transition-all duration-300"
            >
              <ul className="pl-5">
                <li className="my-10">
                  <div>
                    Kontaktieren Sie unseren Kundenservice gerne telefonisch
                    unter{" "}
                    <a className="underlined-link" href="#">
                      +49 (0) 211 864 700
                    </a>
                    , per{" "}
                    <a className="underlined-link" href="#">
                      E-mail
                    </a>{" "}
                    oder{" "}
                    <a className="underlined-link" href="#">
                      Whatsapp
                    </a>
                    .
                  </div>
                </li>
                <li className="my-10">
                  <a href="#">Häufige Frage (FAQ)</a>
                </li>
                <li className="my-10">
                  <a href="#">Reparatur</a>
                </li>
                <li className="my-5">
                  <a href="#">Geschäfte</a>
                </li>
              </ul>
            </div>
          </div>
          <div className="block border-t mx-5 py-4">
            <button
              onClick={() => handleCollapse(1)}
              className="flex items-center justify-between w-full"
            >
              <div>Services</div>
              <img width={10} src={plusIcon} alt="add" />
            </button>
            <div
              id="collapse2"
              className="collapseable overflow-hidden transition-all duration-300"
            >
              <ul className="pl-5">
                <li className="my-10">
                  <a href="#">Care Service</a>
                </li>
                <li className="my-10">
                  <a href="#">Personalisierung</a>
                </li>
                <li className="my-5">
                  <a href="#">Die Kunst des Schenkens</a>
                </li>
              </ul>
            </div>
          </div>
          <div className="block border-t mx-5 py-4">
            <button
              onClick={() => handleCollapse(2)}
              className="flex items-center justify-between w-full"
            >
              <div>Über Louis Vuitton</div>
              <img width={10} src={plusIcon} alt="add" />
            </button>
            <div
              id="collapse3"
              className="collapseable overflow-hidden transition-all duration-300"
            >
              <ul className="pl-5">
                <li className="my-10">
                  <a href="#">Fashion Shows</a>
                </li>
                <li className="my-10">
                  <a href="#">Kunst & Kultur</a>
                </li>
                <li className="my-10">
                  <a href="#">Maison Louis Vuitton</a>
                </li>
                <li className="my-10">
                  <a href="#">Nachhaltigkeit</a>
                </li>
                <li className="my-10">
                  <a href="#">Neuigkeiten</a>
                </li>
                <li className="my-10">
                  <a href="#">Karriere</a>
                </li>
                <li className="my-5">
                  <a href="#">Fondation Louis Vuitton</a>
                </li>
              </ul>
            </div>
          </div>
          <div className="block border-t mx-5 py-4">
            <button
              onClick={() => handleCollapse(3)}
              className="flex items-center justify-between w-full"
            >
              <div>Folgen Sie uns</div>
              <img width={10} src={plusIcon} alt="add" />
            </button>
            <div
              id="collapse4"
              className="collapseable overflow-hidden transition-all duration-300"
            >
              <ul className="pl-5">
                <li className="my-10">
                  Abbonieren Sie den{" "}
                  <a className="underlined-link" href="#">
                    Newsletter von Louis Vuitton
                  </a>{" "}
                  und erfahren Sie zuerst von unseren neuesten Kollektionen,
                  Kampagnen und Initiativen.
                </li>
                <li className="my-10">
                  <a href="#">Apps</a>
                </li>
                <li className="flex my-10 justify-center gap-7">
                  <a href="#">
                    <img width={25} src={instagramIcon} alt="Instagram" />
                  </a>
                  <a href="#">
                    <img width={25} src={facebookIcon} alt="Facebook" />
                  </a>
                  <a href="#">
                    <img width={25} src={twitterIcon} alt="X" />
                  </a>
                  <a href="#">
                    <img width={25} src={youtubeIcon} alt="YouTube" />
                  </a>
                  <a href="#">
                    <img width={25} src={snapchatIcon} alt="Snapchat" />
                  </a>
                  <a href="#">
                    <img width={25} src={pinterestIcon} alt="Pinterest" />
                  </a>
                  <a href="#">
                    <img width={25} src={foursquareIcon} alt="Foursquare" />
                  </a>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default FooterTop;

2

Answers


  1. Chosen as BEST ANSWER

    This is the right way:

    import {
      facebookIcon,
      foursquareIcon,
      instagramIcon,
      lvLogo,
      pinterestIcon,
      plusIcon,
      snapchatIcon,
      twitterIcon,
      youtubeIcon,
    } from "../utils";
    
    const FooterTop = () => {
      const [collapseStatesActive, setCollapseStatesActive] = useState([]);
      const collapseListRef = useRef([]);
    
      useEffect(() => {
        const collapseList = document.querySelectorAll(".collapseable");
        collapseListRef.current = Array.from(collapseList);
        setCollapseStatesActive(
          Array.from({ length: collapseListRef.current.length }, () => false)
        );
      }, []);
    
      useEffect(() => {
        collapseListRef.current.forEach((item, index) => {
          if (collapseStatesActive[index]) {
            item.style.height = item.scrollHeight + "px";
            console.log("rolled out");
          } else {
            item.style.height = "0px";
            console.log("rolled in");
          }
        });
      }, [collapseStatesActive]);
    
      const handleCollapse = (index) => {
        const newCollapseStates = collapseStatesActive.map((state, i) =>
          i === index ? !state : state
        );
        console.log("New Collapse States:", newCollapseStates);
        setCollapseStatesActive(newCollapseStates);
      };
    
      return (
        <>
          <div className="border-b">
            <div className="mt-8 flex justify-center">
              <img width={200} src={lvLogo} alt="LV Logo" />
            </div>
            <div className="mt-8">
              <div className="block border-t mx-5 py-4">
                <button
                  onClick={() => handleCollapse(0)}
                  className="flex items-center justify-between w-full"
                >
                  <div>Wünschen Sie Beratung?</div>
                  <img width={10} src={plusIcon} alt="add" />
                </button>
                <div
                  id="collapse1"
                  className="collapseable overflow-hidden transition-all duration-300"
                >
                  <ul className="pl-5">
                    <li className="my-10">
                      <div>
                        Kontaktieren Sie unseren Kundenservice gerne telefonisch
                        unter{" "}
                        <a className="underlined-link" href="#">
                          +49 (0) 211 864 700
                        </a>
                        , per{" "}
                        <a className="underlined-link" href="#">
                          E-mail
                        </a>{" "}
                        oder{" "}
                        <a className="underlined-link" href="#">
                          Whatsapp
                        </a>
                        .
                      </div>
                    </li>
                    <li className="my-10">
                      <a href="#">Häufige Frage (FAQ)</a>
                    </li>
                    <li className="my-10">
                      <a href="#">Reparatur</a>
                    </li>
                    <li className="my-5">
                      <a href="#">Geschäfte</a>
                    </li>
                  </ul>
                </div>
              </div>
              <div className="block border-t mx-5 py-4">
                <button
                  onClick={() => handleCollapse(1)}
                  className="flex items-center justify-between w-full"
                >
                  <div>Services</div>
                  <img width={10} src={plusIcon} alt="add" />
                </button>
                <div
                  id="collapse2"
                  className="collapseable overflow-hidden transition-all duration-300"
                >
                  <ul className="pl-5">
                    <li className="my-10">
                      <a href="#">Care Service</a>
                    </li>
                    <li className="my-10">
                      <a href="#">Personalisierung</a>
                    </li>
                    <li className="my-5">
                      <a href="#">Die Kunst des Schenkens</a>
                    </li>
                  </ul>
                </div>
              </div>
              <div className="block border-t mx-5 py-4">
                <button
                  onClick={() => handleCollapse(2)}
                  className="flex items-center justify-between w-full"
                >
                  <div>Über Louis Vuitton</div>
                  <img width={10} src={plusIcon} alt="add" />
                </button>
                <div
                  id="collapse3"
                  className="collapseable overflow-hidden transition-all duration-300"
                >
                  <ul className="pl-5">
                    <li className="my-10">
                      <a href="#">Fashion Shows</a>
                    </li>
                    <li className="my-10">
                      <a href="#">Kunst & Kultur</a>
                    </li>
                    <li className="my-10">
                      <a href="#">Maison Louis Vuitton</a>
                    </li>
                    <li className="my-10">
                      <a href="#">Nachhaltigkeit</a>
                    </li>
                    <li className="my-10">
                      <a href="#">Neuigkeiten</a>
                    </li>
                    <li className="my-10">
                      <a href="#">Karriere</a>
                    </li>
                    <li className="my-5">
                      <a href="#">Fondation Louis Vuitton</a>
                    </li>
                  </ul>
                </div>
              </div>
              <div className="block border-t mx-5 py-4">
                <button
                  onClick={() => handleCollapse(3)}
                  className="flex items-center justify-between w-full"
                >
                  <div>Folgen Sie uns</div>
                  <img width={10} src={plusIcon} alt="add" />
                </button>
                <div
                  id="collapse4"
                  className="collapseable overflow-hidden transition-all duration-300"
                >
                  <ul className="pl-5">
                    <li className="my-10">
                      Abbonieren Sie den{" "}
                      <a className="underlined-link" href="#">
                        Newsletter von Louis Vuitton
                      </a>{" "}
                      und erfahren Sie zuerst von unseren neuesten Kollektionen,
                      Kampagnen und Initiativen.
                    </li>
                    <li className="my-10">
                      <a href="#">Apps</a>
                    </li>
                    <li className="flex my-10 justify-center gap-7">
                      <a href="#">
                        <img width={25} src={instagramIcon} alt="Instagram" />
                      </a>
                      <a href="#">
                        <img width={25} src={facebookIcon} alt="Facebook" />
                      </a>
                      <a href="#">
                        <img width={25} src={twitterIcon} alt="X" />
                      </a>
                      <a href="#">
                        <img width={25} src={youtubeIcon} alt="YouTube" />
                      </a>
                      <a href="#">
                        <img width={25} src={snapchatIcon} alt="Snapchat" />
                      </a>
                      <a href="#">
                        <img width={25} src={pinterestIcon} alt="Pinterest" />
                      </a>
                      <a href="#">
                        <img width={25} src={foursquareIcon} alt="Foursquare" />
                      </a>
                    </li>
                  </ul>
                </div>
              </div>
            </div>
          </div>
        </>
      );
    };
    
    export default FooterTop;
    

  2. It has to do with the collapseList. When you initialize this list the items haven’t appeared on the screen, so then the collapseList is empty which causes the collapseStatesActive list to be empty as well.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search