1

Function component is used here

export default function Account() {

defining const with inputs as objects

const [state, setState] = useState({
  profile: true,
  orders: false,
  returns: false,
  coupon: false,
  referrals: false,
  rewards: false,
  redeem: false,
  address: false,
});

function to update state. I want to update state with setting all values in object to false and update specified key that is passes by onClick

function activeHandler(key) {
  setState((prevState) => {
    Object.keys(prevState).forEach((key) => {
      if (key == res) {
        prevState[key] = true;
      } else {
        prevState[key] = false;
      }
    });
    console.log(state);
    return prevState;
  });
}

JSX element, here onClick is used to pass key to function which is used to update state

return (
  <>
    <li
      className={
        state.profile
          ? "py-3 px-3 border-bottom active"
          : "py-3 px-3 border-bottom"
      }
      onClick={() => activeHandler("profile")}
    >
      Profile
    </li>
    <li
      className={
        state.orders
          ? "py-3 px-3 border-bottom active"
          : "py-3 px-3 border-bottom"
      }
      onClick={() => activeHandler("orders")}
    >
      Orders
    </li>
  </>
);

1 Answer 1

2

You don't say there is any issue or ask for help with anything, but it's clear your activeHandler callback function is simply mutating state so I'll assume that's the issue you are asking for help with. The returned state necessarily needs to be a new object reference. Shallow copy any state and nested state that is being updated.

Example:

function activeHandler(key) {
  setState((prevState) => ({
    ...prevState,           // <-- shallow copy previous state
    [key]: !prevState[key], // <-- toggle value by key
  }));
}

Update

I want to set all prevState to false first and then update the state where I want specified key to be true

In this case I'd suggest creating a "default" object with all properties set false to be used as a "template" object, shallow copied then specific property overridden.

Example:

const defaultState = {
  profile: false,
  orders: false,
  returns: false,
  coupon: false,
  referrals: false,
  rewards: false,
  redeem: false,
  address: false,
};

...

function activeHandler(key) {
  setState({
    ...defaultState, // <-- shallow copy default state value
    [key]: true,     // <-- override value by key
  }));
}

Suggestion

Since it seems you want only one "active" property at-a-time I'd suggest storing only the active key and checking that during the render.

Example:

const [active, setActive] = useState();

...

return (
  <>
    <li
      className={
        [
          "py-3 px-3 border-bottom",
          active === 'profile' ? 'active' : null
        ]
          .filter(Boolean)
          .join(" ")
      }
      onClick={() => setActive("profile")}
    >
      Profile
    </li>
    <li
      className={
        [
          "py-3 px-3 border-bottom",
          active === 'orders' ? 'active' : null
        ]
          .filter(Boolean)
          .join(" ")
      }
      onClick={() => setActive("orders")}
    >
      Orders
    </li>
  </>
);
Sign up to request clarification or add additional context in comments.

2 Comments

i want to set all prevState to false first and then update the state where i want specified key to be true
@PonnuSudesh I see. I've updated my answer with an implementation and a suggestion, please do check them out when you can.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.