1

I am new to Gatsby. I have lost with what to do here... please help me...... I want to show only one element(h4) when I click a button. For example, I have 5 plans and each plan has one button and one h4 tag. When I click the third button, only the third h4 tag will shows. As expected by my code, when the button is clicked it displays every element's h4 tag of the map. Is there any way I could active/inactive the component for just one element of the map in this case? Thank you in advance.

  import React, { useState } from "react"

  const TourPage = ({
      const [isOpen, setOpen] = React.useState(false)
      const toggleOpen = () => {
        setOpen(!isOpen)
      }

  return (
        <article>
           {plans.map((plan, index) => {
              return (
                <div key={index}>
                    <button
                      className="btn"
                      onClick={toggleOpen}
                    > button </button>
                    <div
                      className={`${isOpen ? "active" : "inactive"}`}
                    >
                      <h4>{plan.iternary}</h4>
                    </div>
                 </div>
               )
            })}
        </article>
junjun
  • 13
  • 2
  • it is happening because your render loop takes into account the isOpen state variable as it is the same for all indexes..check this another SO [answer](https://stackoverflow.com/questions/55987953/how-do-i-update-states-onchange-in-an-array-of-object-in-react-hooks) – Thakur Karthik Jun 20 '20 at 13:59

1 Answers1

1

You need to have multiple states, state for each plan.

Here is a simple example, you can achieve it however you like, but the concept is the same: manage multiple states within the component.

const plans = [{ id: `id1`, iternary: "a1" }, { id: `id2`, iternary: "a2" }];

const INITIAL = {
  id1: false,
  id2: false
};

const TourPage = () => {
  const [openManager, setOpenManager] = React.useState(INITIAL);

  return (
    <article>
      {plans.map(plan => {
        const onClick = () => {
          setOpenManager(prev => ({ ...prev, [plan.id]: !prev[plan.id] }));
        };
        return (
          <div key={plan.id}>
            <button className="btn" onClick={onClick}>
              button
            </button>
            <div className={`${openManager[plan.id] ? "active" : "inactive"}`}>
              <h4>{plan.iternary}</h4>
            </div>
          </div>
        );
      })}
    </article>
  );
};

Edit empty-bush-ks4zw

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • Thank you so much. It is working perfectly. I tried to understand but I couldn't understand 100% this part. ill be appreciate it if you can explain this. Thank you. :) const onClick = () => { setOpenManager(prev => ({ ...prev, [plan.id]: !prev[plan.id] })) } – junjun Jun 20 '20 at 23:39
  • @junjun Its called functional updates, see https://reactjs.org/docs/hooks-reference.html#functional-updates – Dennis Vash Jun 21 '20 at 17:09