Home > Back-end >  React change useState boolean for current element in map loop
React change useState boolean for current element in map loop

Time:07-26

i got react question. I am looping to render couple elements. onClick i want to change state for current element in loop. I manage to make it work with creating an object.

like this:

const [isOpen, setIsOpen] = useState({
    preferences: true,
    beanType: false,
    quantity: false,
    grindOption: false,
    deliveries: false
});

function  toggle(i) {
    setIsOpen({...isOpen, [i]: !isOpen[i]});
}

return (
    <form action="#" className="accordion stack space-9">
        {props.data.map((curGroup, i) => (
            <div className="accordion__group" id={curGroup.tab} key={curGroup.id}>
                <header className="accordion__header" onClick={() => toggle(curGroup.tab)}>
                    <h2 className="title-2 text-neutral-4">{curGroup.title}</h2>
                    <svg className="accordion__arrow" data-open={isOpen[curGroup.tab]} width="24" height="24"
                         viewBox="0 0 19 11">
                        <use href="assets/sprites.svg#arrow"/>
                    </svg>
                </header>
            </div>
        ))}
    </form>
);

Before this i had this code. Which changed state for all the rendered items and opened menu.

    const [isOpen, setIsOpen] = useState(false);

function  toggle(i) {
    setIsOpen(!isOpen);
}

return (
    <form action="#" className="accordion stack space-9">
        {props.data.map((curGroup, i) => (
            <div className="accordion__group" id={curGroup.tab} key={curGroup.id}>
                <header className="accordion__header" onClick={toggle}>
                    <h2 className="title-2 text-neutral-4">{curGroup.title}</h2>
                    <svg className="accordion__arrow" data-open={isOpen} width="24" height="24"
                         viewBox="0 0 19 11">
                        <use href="assets/sprites.svg#arrow"/>
                    </svg>
                </header>
            </div>
        ))}
    </form>
);

I feel like creating the object in state is more hard coded. Could someone help me how to make this more dynamic? Thank you.

CodePudding user response:

You'll have to do some hard-coding because there's one value that's different from the others - the preferences: true. As for the others, they can be left out of the object completely (as long as other code that uses the object can also understand undefined as well as false).

const [isOpen, setIsOpen] = useState({
    preferences: true,
});

and change

data-open={isOpen[curGroup.tab]}

to

data-open={isOpen[curGroup.tab] ?? false}
  • Related