Home > Net >  React.js close all the previous containers at the same time
React.js close all the previous containers at the same time

Time:09-22

I got the container with children coming from props.[Container][1]

[1]: https://i.stack.imgur.com/3Y7Qm.png . When i click the arrow button it shows the content of the container. [Content][1]

[1]: https://i.stack.imgur.com/A8eZH.png . When i open the content container i want other containers to close . For now i can only close them with clicking the arrow button again.[Open Content][1]

[1]: https://i.stack.imgur.com/REh57.png .Here is my code `

import { useState } from "react";

export default function Question(props) {
    const [clicked, setClicked] = useState(false);
    function clickedElement() {
        return setClicked(!clicked);
    }

    return (
        <div className="question-cont">
            <div className="question-cont-inner">
                <h3>{props.head}</h3>
                <button onClick={() => clickedElement()}>
                    {clicked ? (
                        <img src={props.img2} />
                    ) : (
                        <img src={props.img} />
                    )}{" "}
                </button>
            </div>
            {clicked ? <p>{props.description}</p> : ""}
        </div>
    );
}

Here is the my parent component

import Question from "../components/Question";
import questions from "../components/Questions";

export default function Sorular() {
    const questionList = questions.map((question) => {
        return (
            <Question
                key={question.id}
                id={question.id}
                head={question.head}
                description={question.description}
                img={question.img}
                img2={question.img2}
            />
        );
    });
    return (
        <div className="sorular-container">
            <div className="sorular-top">
                <div className="sorular-top-back-img">
                    <a href="/">
                        <img
                            src="./images/right-arrow-colorful.png"
                            id="right-arrow-img"
                        />
                    </a>
                </div>
                <div className="sorular-top-head">
                    <img src="./images/conversation.png" />
                    <h4>Sıkça Sorulan Sorular</h4>
                </div>
            </div>
            <div className="sorular-bottom">{questionList}</div>
        </div>
    );
}

`

CodePudding user response:

You need to remove your const [clicked, setClicked] = useState(false); state variable from the component itself and move it into parent:

In parent add this at the beggining and modify questionList:

const [clickedElementId, setClickedElementId] = useState(null);

const questionList = questions.map((question) => {
    return (
        <Question
            key={question.id}
            id={question.id}
            head={question.head}
            description={question.description}
            img={question.img}
            img2={question.img2}
            isOpened={question.id === clickedElementId}
            onClickedElement={() => setClickedElementId(
                question.id === clickedElementId ? null : question.id
            )} 
        />
    );
});

And in the Question.jsx, swap button for the following:

<button onClick={() => props.onClickedElement()}>
    {props.isOpened ? (
        <img src={props.img2} />
    ) : (
        <img src={props.img} />
    )}{" "}
</button>
// and later:
{props.isOpened ? <p>{props.description}</p> : ""}

This works by your app holding id of only one, currently open question, and swap it based on clicked element.
Note that questionId should be unique amongst all Question components, but you probably use .map to render them so you should use the same variable as you are passing into Question's key prop while rendering.

  • Related