反应切换菜单

时间:2017-06-02 21:15:49

标签: reactjs ecmascript-6 event-handling toggle

我正尝试从此示例构建一个Toggle右侧菜单:how-to-build-a-sliding-menu-using-react-js"

问题是React.createClass已被弃用,因此我必须更改代码并停止工作我获取内容但无法访问处理程序任何人告诉我应该采取哪些步骤来解决此问题!所以,如果我点击我的按钮,我会收到此错误:

  

未捕获的TypeError:无法读取未定义的属性'show'

ToggleMenu

import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import localStyles from './ToggleMenu.scss';
import { themr } from 'react-css-themr';
import { Menu } from '../../components';
import { MenuItem } from '../../components';

@themr('ToggleMenu', localStyles)

export default class ToggleMenu extends React.Component {

  showRight() {
    this.refs.right.show();
  }

  constructor(props) {
    super(props);
    this.showRight = this.showRight.bind(this);
  }

  render() {

    return (
      <div>
      <button onClick={this.showRight}>Show Right Menu!</button>
      <Menu ref={right => this.right = right} alignment="right">
      <MenuItem hash="first-page">First Page</MenuItem>
      <MenuItem hash="second-page">Second Page</MenuItem>
      <MenuItem hash="third-page">Third Page</MenuItem>
      </Menu>
      </div>
    );
  }
}

菜单

import React from 'react';

export default class Menu extends React.Component {
    constructor() {
        super();
        this.state = {
            visible: false
        }
    };

    show() {
        this.setState({visible: true});
        document.addEventListener("click", this.hide.bind(this));
    }

    hide() {
        this.setState({visible: false});
        document.removeEventListener("click", this.hide.bind(this));
    }

    render() {
        return (
            <div className="menu">
                <div className={(this.state.visible ? "visible " : "") + this.props.alignment}>{this.props.children}</div>
            </div>
        );
    }
}

菜单项

import React from 'react';

export default class MenuItem extends React.Component {
    navigate(hash) {
        window.location.hash = hash;
    }

    render() {
        return (
            <div className="menu-item" onClick={this.navigate.bind(this, this.props.hash)}>{this.props.children}</div>
        );
    }
}

1 个答案:

答案 0 :(得分:1)

问题是您要将引用分配给this.right,您需要将showRight方法更新为以下内容:

showRight() {
  this.right.show();
}

我还使用箭头函数来避免在构造函数中绑定函数。

import React, { PureComponent } from 'react';

export default class ToggleMenu extends PureComponent {

  showRight = () => {
    this.right.show();
  }

  render() {

    return (
      <div>
      <button onClick={this.showRight}>Show Right Menu!</button>
      <Menu ref={right => this.right = right} alignment="right">
      <MenuItem hash="first-page">First Page</MenuItem>
      <MenuItem hash="second-page">Second Page</MenuItem>
      <MenuItem hash="third-page">Third Page</MenuItem>
      </Menu>
      </div>
    );
  }
}

并确保使用PureComponent以避免在不需要时呈现组件。

修改

Menu类不是反应方式,如果你想隐藏一个元素,你应该做如下的事情:

import React from 'react';

export default class Menu extends React.Component {
    state = {
      visible: false,
    };

    show() {
      this.setState({ visible: true });
    }

    hide() {
      this.setState({ visible: false });
    }

    render() {
      const { visible } = this.state;

      return (
        <div className="menu">
          { 
            visible &&
              <div className={this.props.alignment}>{this.props.children}</div>
          }
        </div>
      );
    }
}

如果visible === true,那么div将呈现,否则不会。我删除了侦听器,我们不做反应,而是需要在要让用户单击的元素上定义onClick回调以隐藏菜单。