1

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.

3
  • 1
    In the state, you haven't written menuClicked, thisMenu and ulSIdenavClass. you need to write them too when you are initializing state. Commented Nov 15, 2017 at 11:34
  • menuClicked is the name of the menu. I passed it as a param of handleClick(menuClicked). it will replace like this.setState({ ...this.state, "homeMenuStatus" => menuClicked: 'active', ulSidenavClass: 'block-display' }); Commented Nov 15, 2017 at 11:39
  • ok. I get it. But where are you getting the old state? I guess you have to pass previous State too. Commented Nov 15, 2017 at 12:10

3 Answers 3

1

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'
                  }
            }
    })}))

}
Sign up to request clarification or add additional context in comments.

1 Comment

Happy to have helped.
0

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 :)

Comments

0

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
  });
}

1 Comment

Thanks for the answer. This should work except I need to map through all the menustate item not only the one user clicked. so I think if I change find to map this should work for me. :-)

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.