Reputation: 6976
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
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
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