user14637541
user14637541

Reputation:

Toggle classes to parent component - React

I am trying to understand basic React web design practices, but I haven't found a proper explanation on how to toggle classes also to the parent components. In vanilla JS would have been easier by adding an Event Handler to the document. I have a button inside the MobileMenu component which upon click, shows the menu and changes its appearance. I would like to toggle a class also to the div wrapper of my Home function in order to move from left the body when opening the menu. I read that it can be done by setting the state in the parent component and pass a function from the child to the parent component but I'm getting only errors and I'm unable to find a proper example. This is my current working code which only toggles the classes inside the component. Thank you in advance for any explanation.

MobileMenu component:

class MobileMenu extends React.Component {

    state = {
        isSwitchOn: false,
    }

    render() {

        console.log(this.state.isSwitchOn)
        const isOn = this.state.isSwitchOn;

        return (
            <div className="mobileNavigation">
                <div className="btnMenuContainer">
                    <button className={isOn ? "hamburger is-active" : "hamburger "}
                        onClick={() => this.setState({ isSwitchOn: !isOn })} type="button">
                    </button>
                </div>
                <div className={isOn ? "mobileNavContainer showMobileNav" : "mobileNavContainer" }>
                </div>
            </div>
        );
    }
}

export default MobileMenu

Home Function:

export default function Home({ children }) {

  return (
    <div>
      <Global />
      <MobileMenu />
      <SectionHero>
        <h1>Title</h1>
        <p>Paragraph</p>
      </SectionHero>
    </div>
  );
}

Upvotes: 0

Views: 994

Answers (1)

Jason Bellomy
Jason Bellomy

Reputation: 562

If you want the parent to be able to switch classes based on the state, then the parent needs to hold the state (state should go at the top most level in which it is needed and then flow downwards as props). Then the parent needs to pass the state and the onChange function down to the child so that it can use it to call the parent function and update the state, like so:

home class:

class Home extends React.Component {
  constructor() {
    super();
    this.state = this.getInitialState();
  }
  getInitialState() {
    return {
      isSwitchOn: false
    }
  }
  handleOnClick = () => {
    this.setState({isSwitchedOn: !this.state.isSwitchedOn});
  };
  render() {
    cosnt {isSwitchedOn} = this.state; //<-- Now that you have in state on the parent, you can use it here in the parent to do what ever logic you need to do with it.
    return (
      <div className={isSwitchedOn ? "someClass" : "someOtherClass"} >
        <Global />
        <MobileMenu
          isSwitchedOn={isSwitchedOn}
          onClick={this.handleOnClick}
        />
        <SectionHero>
          <h1>Title</h1>
          <p>Paragraph</p>
        </SectionHero>
      </div>
    );
  }
}

Mobile Menu function:

export default function MobileMenu({isSwitchedOn, onClick}) {
    return (
        <div className="mobileNavigation">
            <div className="btnMenuContainer">
                <button className={"hamburger" + (isSwitchedOn ? " is-active" : "")}
                        onClick={onClick} type="button" />
            </div>
            <div className={"mobileNavContainer" + (isSwitchedOn ? " showMobileNav" : "")} />
        </div>
    );
}

Also, in your Mobile menu you can simplify your className logic for your button and DIV, as they both have a constant that is always on.

Upvotes: 1

Related Questions