Arjita Mitra
Arjita Mitra

Reputation: 962

Update a nested state array based on selected value

I am trying to update which menu item was clicked and therefore change the class accordingly. I have tried different way suggested to do it but couldn't make it work.

Heres my code:

constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
        this.state = {
            menuState: [
                {
                    menuName: 'homeMenuStatus',
                    homeMenuStatus: 'inactive',
                    ulSidenavClass: "nav child_menu no-display"
                },
                {
                    menuName: 'accountMenuStatus',
                    accountMenuStatus: 'active',
                    ulSidenavClass: "nav child_menu block-display"
                },
                {
                    menuName: 'contactMenuStatus',
                    peopleMenuStatus: 'inactive',
                    ulSidenavClass: "nav child_menu no-display"
                },

            ]
        }
    }

handleClick(menuClicked) {
        this.state.menuState.map((name, index) => {
            let thisMenu = name.menuName;

            if(name.menuName == menuClicked) {
                if(this.state.menuClicked === 'active') {
                    this.setState({
                        ...this.state,
                        menuClicked: 'inactive',
                        ulSidenavClass: 'block-display height-adjust'
                    });
                } else {
                    this.setState({
                        ...this.state,
                        menuClicked: 'active',
                        ulSidenavClass: 'block-display'
                    });
                }
            } else {
                this.setState({
                    ...this.state,
                    thisMenu: 'inactive',
                    ulSidenavClass: 'block-display height-adjust'
                });
            }
        });
    }

HTML:

    <div>
        <ul>
            <li className={this.state.menuState[0].homeMenuStatus}>
                <a onClick={() => this.handleClick('homeMenuStatus')}>Home </a>
                <ul className={this.state.menuState[0].ulSidenavClass}>
                    <li>
                        <a href="#">Dashboard</a>
                    </li>
                    <li>
                        <a href="#">Activities</a>
                    </li>
                </ul>
            </li>
        </ul>
    </div>

My state object is not getting changed. Must be doing something wrong in setState(). Can anyone please guide me.

Upvotes: 1

Views: 460

Answers (3)

Dane
Dane

Reputation: 9572

You must handle this in another way. The following handleClick function should solve your issue:

handleClick(menuClicked) {
  let menuStateDup = this.state.menuState.slice();
  let itemToUpdate = menuStateDup.find((element) => (
    element.menuName === menuClicked
  ));
  if ( itemToUpdate.menuClicked === 'active' ) {
    itemToUpdate.menuClicked = 'inactive';
    itemToUpdate.ulSidenavClass = 'block-display height-adjust';
  } else {
    // do vice-versa
  }
  this.setState({
    menuState: menuStateDup
  });
}

Upvotes: 0

Shubham Khatri
Shubham Khatri

Reputation: 281894

You are incorrectly updating the state, use prevState syntax and return the mapped updated values like

handleClick(menuClicked) {
    this.setState((prevState) => ({menuState: prevState.menuState.map((name, index) => {
           if(name.menuName === menuClicked) {
              if(name.menuClicked === 'active') {
                  return {
                      ...name,
                      menuClicked: 'inactive,
                      ulSidenavClass: 'block-display height-adjust'
                  }
              } else {
                  return {
                      ...name,
                      menuClicked: 'active,
                      ulSidenavClass: 'block-display'
                  }
              }

           } else {
                 return {
                      ...name,
                      menuClicked: 'inactive,
                      ulSidenavClass: 'block-display height-adjust'
                  }
            }
    })}))

}

Upvotes: 1

jovi De Croock
jovi De Croock

Reputation: 615

You are setting your global state instead off the state of the specific object, what would help is mapping over the menu's setting them and just appending the new menu to the state.

You are setting on this.state instead off your this.state.desiredItem

Feel free to ask questions, good luck :)

Upvotes: 0

Related Questions