Udders
Udders

Reputation: 6976

React slide in navigation on button click

I am starting to work with React and trying to get my head around it. I am currently trying to build a navigation component that slides in when a button is clicked (the button lives in another component).

Here is my code so far,

  class Application extends React.Component {

      constructor() {
        super();
        this.state = {
            sidebarOpen:false
        }
      }

      handleViewSidebar() {
          this.state.sidebarOpen = !this.state.sidebarOpen;
      }

      render() {
          return(
              <div>
                  <Navigation isOpen={this.state.sidebarOpen} toggleSidebar={this.handViewSidebar}/>
                  <Header isOpen={this.state.sidebarOpen} />
             </div>
           );
      }
    }

    class Header extends React.Component {
        constructor(props) {
           super(props);
           this.slideMenu = this.slideMenu.bind(this);
        }

        render() {
            return(
                <header>
                     <div className="container">
                         <h1><a>AppName</a></h1>
                         <div className="user__actions">
                             <a>Notifications</a>
                             <a onClick={this.slideMenu}>Menu</a>
                         </div>
                      </div>
                  </header>
            );
        }

        slideMenu() {
            this.setState({sidebarOpen:true});
            console.log(this.state);
        }
    }

    class Navigation extends React.Component {
        constructor(props) {
        super(props);
    }

    render() {
        return(
            <nav className={(this.props.sidebarOpen ? "site__navigation visible" : "site__navigation")}>
                <a>Friends</a>
                <a>Matches</a>
                <a>Messages</a>
                <a>Profile</a>
                <a>Search</a>
            </nav>
        )  
    }

}

/*
 * Render the above component into the div#app
 */
React.render(<Application />, document.getElementById('app'));

What I am finding is that one state is passed through all my components? In my slideMenu function i console log this.state but it is null. I cannot work out how to add a class to Navigation componenet on click of button to make the nav bar visible?

Upvotes: 1

Views: 2261

Answers (2)

Piyush
Piyush

Reputation: 1193

 class Application extends React.Component {

      constructor() {
        super();
        this.state = {
            sidebarOpen:false
        }
      }

      handleViewSidebar() {
          this.setState({sidebarOpen:!this.state.sidebarOpen});
      }

      render() {
          return(
              <div>
                  <Navigation isOpen={this.state.sidebarOpen} toggleSidebar={this.handleViewSidebar.bind(this)}/>
                  <Header isOpen={this.state.sidebarOpen}  toggleSidebar={this.handleViewSidebar.bind(this)}/>
             </div>
           );
      }
    }

    class Header extends React.Component {

        render() {
            return(
                <header>
                     <div className="container">
                         <h1><a>AppName</a></h1>
                         <div className="user__actions">
                             <a>Notifications</a>
                             <a onClick={this.props.toggleSidebar}>Menu</a>
                         </div>
                      </div>
                  </header>
            );
        }

        
    }

    class Navigation extends React.Component {
        constructor(props) {
        super(props);
    }

    render() {
        return(
            <nav className={(this.props.isOpen === true ? "site__navigation visible" : "site__navigation")}>
                <a>Friends</a>
                <a>Matches</a>
                <a>Messages</a>
                <a>Profile</a>
                <a>Search</a>
            </nav>
        )  
    }

}

This will work for you, there were little mistakes which i corrected for you

Upvotes: 1

Daniel Andrei
Daniel Andrei

Reputation: 2684

Your example code is not working mostly because of small mistakes such as :

Directly assigning state (which will not call render to update your application). You need to update your app through setState() calls.

handleViewSidebar() {
    this.state.sidebarOpen = !this.state.sidebarOpen;
}

Should be

handleViewSidebar() {
    this.setState({sidebarOpen: !this.state.sidebarOpen});    
}

and passing props with different names but using them with the initial name. Example: sidebarOpen vs isOpen

You also don't need "slideMenu" as you can pass handleViewSidebar as a prop and call it directly from the Header component.

Upvotes: 0

Related Questions