【问题标题】:Material UI - Open LeftNav / Drawer on AppBar clickMaterial UI - 在 AppBar 点击打开 LeftNav / Drawer
【发布时间】:2015-04-25 20:23:44
【问题描述】:

我正在发现 ReactJS 和 material-ui (http://material-ui.com/)。

我尝试为我的应用程序创建一个默认模板。 我想在单独的组件中使用 AppBar 和 LeftNav(在新版本的 Drawer 中重命名)。

默认情况下,AppBar 上有一个菜单按钮。我想用它来打开 LeftNav 但我不知道如何调用我的 LeftBarComponent 组件函数来打开它。

我几乎了解如何在组件之间进行通信,但就我而言,我不知道该怎么做,因为没有关于它的文档。 我唯一知道打开 LeftNav 元素是使用 LeftNav.toggle()

http://material-ui.com/#/components/left-nav

感谢您的帮助。

Default.jsx

use strict';

var React = require('react');
var pageStore = require('../../stores/page');

var MainNavbar = require('../modules/navbar.jsx');
var LeftNavbar = require('../modules/leftbar.jsx');

var getState = function() {
  return {
    title: pageStore.get().title
  };
};

var DefaultComponent = React.createClass({
  mixins: [pageStore.mixin],
  componentDidMount: function() {
    pageStore.emitChange();
  },
  getInitialState: function() {
    return getState();
  },
  render: function() {
    return (
      /* jshint ignore:start */
      <div className="main-container">
        <MainNavbar />
        <LeftNavbar />
        <div className="content">
          {this.props.children}
        </div>
      </div>
      /* jshint ignore:end */
    );
  },
  // Event handler for 'change' events coming from store mixins.
  _onChange: function() {
    this.setState(getState());
  }
});

module.exports = DefaultComponent;

navbar.jsx

'use strict';

var React = require('react');
var routeActions = require('../../actions/routes');

var MUI = require('material-ui');
var AppBar = MUI.AppBar;

// Navbar Component
// Application main menu
// Usage: <Navbar />
var NavbarComponent = React.createClass({
  render: function() {
    return (
      /* jshint ignore:start */
      <AppBar title="MyApp" onMenuIconButtonTouchTap={ this._handleClick }>
        <div className="clear"></div>
      </AppBar>
      /* jshint ignore:end */
    );
  },
  _handleClick: function()
  {
    console.log('ok');
  }
});

module.exports = NavbarComponent;

leftbar.jsx

'use strict';

var React = require('react');
var routeActions = require('../../actions/routes');

var MUI = require('material-ui');
var LeftNav = MUI.LeftNav;
var MenuItem = MUI.MenuItem;

var menuItems = [
  { route: 'home', text: 'Home' },
  { route: 'about', text: 'About' },
];

// LeftBar Component
// Application left menu
// Usage: <LeftBar />
var LeftBarComponent = React.createClass({
  render: function() {
    return (
      /* jshint ignore:start */
      <LeftNav menuItems={menuItems} docked={false} />
      /* jshint ignore:end */
    );
  },
  _handleClick: function()
  {
    console.log('ok');
  }
});

module.exports = LeftBarComponent;

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    在这种情况下,您需要通过组件向上传递事件,然后再向下传递。

        <MainNavbar onClickMenu=this.onClickMenu/>
        <LeftNavbar isOpen=this.state.leftNavIsOpen/>
    

    但是,将它与 Reactjs 结合使用并不是最佳选择,因为 LeftNav 材质组件不会对属性做出反应,而是对方法调用做出反应,就像你说的那样。

    要解决此问题,您可以检查 LeftNav 渲染方法,该方法检查当前状态,并在需要时调用 toggle()。原则上这违背了 React 的思维方式,因为状态包含在特定的子组件中,而不是在处理它的 DefaultComponent 中。

    render:function(){
      if(this.props.isOpen){
         LeftNav.open();
      }
      return ...
    

    【讨论】:

    【解决方案2】:

    为了澄清 steinso 所说的,您需要使用 Flux 架构将事件发送到 Action,然后在 Store 中更改它。然后使用 EventEmitter 调度一个发出更改事件。这将在具有更新状态的受影响组件上触发渲染。

    https://facebook.github.io/flux/

    如果您必须将它们分开,那将是最好的方法。但是,如果您可以将它们放在同一个组件中,例如“Main”,那么您可以简单地使用 ref 属性并引用该组件。

    module.exports = React.createClass({
    
      childContextTypes: {
        muiTheme: React.PropTypes.object
      },
    
      getChildContext: function() {
        return {
          muiTheme: ThemeManager.getCurrentTheme()
        };
      },
    
      _toggleNav: function(){
        this.refs.leftNav.toggle();
      },
    
      render: function() {
        return (
          <div>
            <mui.LeftNav
              ref='leftNav'
              menuItems={menuItems}
              docked={false} />
            <mui.AppBar
              title='Default'
              onLeftIconButtonTouchTap={this._toggleNav} />
          </div>
        );
      }
    
    });
    

    像这样。

    【讨论】:

      【解决方案3】:

      我正在将 React 与 Material-UI 一起使用,并且我已使用 AppBar 中的 onLeftIconButtonTouchTap={this.handleToggle} 事件来完成此操作。更详细的可以参考官方文档http://www.material-ui.com/#/components/app-bar

      App.js

      import React from 'react';
      import AppBar from 'material-ui/AppBar';
      import Drawer from 'material-ui/Drawer';
      import MenuItem from 'material-ui/MenuItem';  
      import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; 
      import Dashboard from './Dashboard/dashboard.js';
      import Information from './Information/information.js';
      import './App.css';
      
      class App extends React.Component {
      
        constructor(props) {
          super(props);
          this.state = {open: false};
        }
      
        handleToggle = (event) => this.setState({open: !this.state.open});
      
        render() {
      
          const {styleFromProps} = this.props;
          const contentStyle = {  ...styleFromProps, transition: 'margin-left 450ms cubic-bezier(0.23, 1, 0.32, 1)' };
      
          if (this.state.open) {
            contentStyle.marginLeft = 256;
          }
      
          return (
              <Router>
                <div>
                <AppBar title="AppTitle" onLeftIconButtonTouchTap={this.handleToggle} />
      
                  <Drawer containerStyle={{height: 'calc(100% - 64px)', top: 64}} docked={true} width={200} open={this.state.open} zDepth={2}>
                    <Link to="/dashboard" style={{ textDecoration: 'none' }}><MenuItem>Dashboard</MenuItem></Link>
                    <Link to="/information" style={{ textDecoration: 'none' }}><MenuItem>Information</MenuItem></Link>
                  </Drawer>
      
                  <Route path="/dashboard" component={(props) => <Dashboard {...props} open={this.state.open}/>} />
                  <Route path="/information" component={(props) => <Information {...props} open={this.state.open}/>} />
                </div>
              </Router>
          );
        }
      }
      
      export default App;
      

      我想它会对你有所帮助。

      【讨论】:

      • 谢谢@Rohit 它帮助了我。这就是我要找的。​​span>
      猜你喜欢
      • 2015-09-26
      • 2018-08-09
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      • 2021-11-25
      • 2019-05-24
      • 1970-01-01
      • 2021-12-20
      相关资源
      最近更新 更多