Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Material-UI Left Drawer in App Bar won't close on overlay click or menu item click in React

I am having an issue I can't seem to pin down where my LeftDrawer for my App Bar isn't closing if I click a menu item or the overlay (Not sure if this is an option, or possible with react components). Ideally, I would like both options to close the Drawer. Thank you in advance for taking your time to look at this!

This is my Navbar class I am using to toggle open the LeftDrawer:

// Dependencies
import React from 'react';

//Comonents
import LeftDrawer from './left-drawer.jsx';

// Styles
import './nav-bar.scss';
import AppBar from 'material-ui/AppBar';

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

    this.state = {
      open: false
    };
  }

  toggleDrawer(){
    this.setState({
      open: !this.state.open
    });
  }

  render(){
    return (
      <div className='nav-bar'>
        <AppBar title='My App' onLeftIconButtonTouchTap={() => this.toggleDrawer()}/>
        <LeftDrawer open={this.state.open} onToggleDrawer={this.toggleDrawer.bind(this)} />
      </div>
    );
  }
}

export default NavBar;

This is the LeftDrawer class with the MenuItems:

// Dependencies
import React from 'react';
import { Link } from 'react-router-dom';

// Styles
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';

export default class LeftDrawer extends React.Component {
constructor(props) {
    super(props);
    this.state = {open: false};
}

handleToggle() {
    this.setState({open: !this.state.open});
}

handleClose() {
    this.setState({open: false});
}

render() {
    return (
        <div>
            <Drawer
                docked={false}
                width={200}
                open={this.props.open}
                onRequestChange={(open) => this.setState({open})}
            >
                <Link to="/home"><MenuItem onTouchTap={this.handleClose.bind(this)}>Home</MenuItem></Link>
                <Link to="/topics"><MenuItem onTouchTap={this.handleClose.bind(this)}>404</MenuItem></Link>
            </Drawer>
        </div>
        );
    }
}
like image 808
Shawn Avatar asked Jun 04 '17 05:06

Shawn


2 Answers

Reason is you are controlling the Drawer by props values (state value of parent component) so you need to update the parent state value by calling a function from child.

Define a handleClose function in parent:

handleClose() {
    this.setState({open: false})
}

pass this function to LeftDrawer component:

<LeftDrawer open={this.state.open} handleClose={this.handleClose.bind(this)} onToggleDrawer={this.toggleDrawer.bind(this)} />

Then inside child handleClose function call that parent handleClose function:

handleClose() {
    this.props.handleClose();
}

Full Code:

import AppBar from 'material-ui/AppBar';

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

    this.state = {
      open: false
    };
    this.toggleDrawer = this.toggleDrawer.bind(this);
    this.handleClose = this.handleClose.bind(this);
  }

  toggleDrawer(){
    this.setState({
      open: !this.state.open
    });
  }

  handleClose(){
    this.setState({open: false})
  }

  render(){
    return (
      <div className='nav-bar'>
        <AppBar title='My App' onLeftIconButtonTouchTap={this.toggleDrawer}/>
        <LeftDrawer open={this.state.open} handleClose={this.handleClose} onToggleDrawer={this.toggleDrawer} />
      </div>
    );
  }
}

export default class LeftDrawer extends React.Component {
  constructor(props) {
      super(props);
      this.state = {open: false};
      this.handleClose = this.handleClose.bind(this);
  }

  handleToggle() {
      this.setState({open: !this.state.open});
  }

  handleClose() {
     this.props.handleClose();
  }

  render() {
    return (
        <div>
            <Drawer
                docked={false}
                width={200}
                open={this.props.open}
                onRequestChange={(open) => this.setState({open})}
            >
                <Link to="/home"><MenuItem onTouchTap={this.handleClose}>Home</MenuItem></Link>
                <Link to="/topics"><MenuItem onTouchTap={this.handleClose}>404</MenuItem></Link>
            </Drawer>
        </div>
    );
  }
}
like image 188
Mayank Shukla Avatar answered Nov 13 '22 13:11

Mayank Shukla


The LeftDrawer component inside NavBar contains onToggleDrawer={this.toggleDrawer} prop which is not used inside LeftDrawer.

Also, seems that handleToggle is unnecessary in the inner component, which should manage the state of the parent.

If anyone lands at this question after some time better read about lifting up state, rather than taking the responses.

like image 40
kalinchernev Avatar answered Nov 13 '22 13:11

kalinchernev