【问题标题】:Show/Hide components in ReactJS在 ReactJS 中显示/隐藏组件
【发布时间】:2015-07-06 22:44:42
【问题描述】:

我们现在在使用 react 时遇到了一些问题,但这有点归结为我们一直在使用 react 的一部分。

我们应该如何显示/隐藏子组件?

这就是我们的编码方式(这只是我们组件的 sn-ps)...

_click: function() {
  if ($('#add-here').is(':empty'))
    React.render(<Child />, $('#add-here')[0]);
  else
    React.unmountComponentAtNode($('#add-here')[0]);
},
render: function() {
  return(
    <div>
      <div onClick={this._click}>Parent - click me to add child</div>
      <div id="add-here"></div>
    </div>
  )
}

最近我一直在阅读一些例子,它应该是这样的:

getInitialState: function () {
  return { showChild: false };
},
_click: function() {
  this.setState({showChild: !this.state.showChild});
},
render: function() {
  return(
    <div>
      <div onClick={this._click}>Parent - click me to add child</div>
      {this.state.showChild ? <Child /> : null}
    </div>
  )
}

我应该一直使用那个 React.render() 吗?它似乎阻止了各种事情,比如shouldComponentUpdate 级联到孩子和e.stopPropagation 之类的事情......

【问题讨论】:

  • 您能否更详细地解释您的第二个解决方案的问题是什么?这实际上是首选的方法。有一个状态属性showChild,当你的div 被点击时你会切换它。调用 setState 然后重新渲染你的组件。
  • @LarsBlumberg。哦。我实际上还没有使用第二种解决方案的经验。我只在一个小应用程序中尝试过,似乎可以工作。我们一直在使用第一个,因为它是以前教给我们的。但是现在我们遇到了诸如stopPropagation 不起作用或者我们需要在父级上触发shouldComponentUpdate 时手动更新子级的问题。但是我还没有真正看到任何关于这种“首选方式”的文档,只有各种教程的示例。那么我们应该一直使用第二种解决方案吗?
  • 是的,第二个是更好的选择。 React 文档和示例不使用 JQuery。文档有很多很棒的信息。 facebook.github.io/react/docs/…
  • @WiredPrairie。好吧,我仍然可以使用 this.refs,我只是很快用 jQuery 编写了它。
  • 根本不使用 jQuery,或者尽可能少地使用 jQuery。任何时候你操作 DOM,你都冒着 React 翻脸的风险。通常会吹出类似于:unable to find component at root '' 的错误

标签: reactjs show-hide


【解决方案1】:

我提供了一个遵循您的第二种方法的工作示例。更新组件的状态是显示/隐藏子项的首选方式。

假设你有这个容器:

<div id="container">
</div>

您可以使用现代 Javascript(ES6,第一个示例)或经典 JavaScript(ES5,第二个示例)来实现组件逻辑:

使用 ES6 显示/隐藏组件

Try this demo live on JSFiddle

class Child extends React.Component {
  render() {
    return (<div>I'm the child</div>);
  }
}

class ShowHide extends React.Component {
  constructor() {
    super();
    this.state = {
      childVisible: false
    }
  }

  render() {
    return (
      <div>
        <div onClick={() => this.onClick()}>
          Parent - click me to show/hide my child
        </div>
        {
          this.state.childVisible
            ? <Child />
            : null
        }
      </div>
    )
  }

  onClick() {
    this.setState(prevState => ({ childVisible: !prevState.childVisible }));
  }
};

React.render(<ShowHide />, document.getElementById('container'));

使用 ES5 显示/隐藏组件

Try this demo live on JSFiddle

var Child = React.createClass({
  render: function() {
    return (<div>I'm the child</div>);
  }
});

var ShowHide = React.createClass({
  getInitialState: function () {
    return { childVisible: false };
  },

  render: function() {
    return (
      <div>
        <div onClick={this.onClick}>
          Parent - click me to show/hide my child
        </div>
        {
          this.state.childVisible
            ? <Child />
            : null
        }
      </div>
    )
  },

  onClick: function() {
    this.setState({childVisible: !this.state.childVisible});
  }
});

React.render(<ShowHide />, document.body);

【讨论】:

  • 这真是太好了。我想实现这一点。但是,如果单击的不是子组件,我还需要删除子组件。你能指导我怎么做吗?
  • @LarsBlumberg 是的,我问过here。请你帮助我好吗。谢谢。
  • 只是一个关于三元something ? &lt;Child /&gt; : null的注释,为什么不使用something &amp;&amp; (&lt;Child /&gt;)呢?昨天注意到这一点,我非常喜欢它
  • @MrMesees 我也喜欢这种情况下的 && 语法。
  • @LarsBlumberg 我是 React 新手,不了解这个核心概念。如果&lt;Child/&gt; 是许多不同&lt;Parents/&gt; 之间共享的组件,那么使用这种设计,每个父级都必须实现显示和隐藏方法,从而产生大量代码重复。我曾考虑在我的项目中使用refs 来避免这个问题(this.child.current.hide()),但这似乎是一种不好的做法。代码重复问题你有解决办法吗?
【解决方案2】:
    /* eslint-disable jsx-a11y/img-has-alt,class-methods-use-this */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import todoStyle from 'src/style/todo-style.scss';
import { Router, Route, hashHistory as history } from 'react-router';
import Myaccount from 'src/components/myaccount.jsx';

export default class Headermenu extends Component {

  constructor(){
  super();

  // Initial state
  this.state = { open: false };

}

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

  componentdidMount() {
    this.menuclickevent = this.menuclickevent.bind(this);
    this.collapse = this.collapse.bind(this);
    this.myaccount = this.myaccount.bind(this);
    this.logout = this.logout.bind(this);
  }

  render() {
    return (
      <div>

        <div style={{ textAlign: 'center', marginTop: '10px' }} id="menudiv" onBlur={this.collapse}>
          <button onClick={this.toggle.bind(this)} > Menu </button>

          <div id="demo" className={"collapse" + (this.state.open ? ' in' : '')}>
            <label className="menu_items" onClick={this.myaccount}>MyAccount</label>
            <div onClick={this.logout}>
              Logout
            </div>
          </div>

        </div>
      </div>
    );
  }

  menuclickevent() {
    const listmenu = document.getElementById('listmenu');
    listmenu.style.display = 'block';
  }



  logout() {
    console.log('Logout');
  }
  myaccount() {
    history.push('/myaccount');
    window.location.reload();

  }


}

【讨论】:

    猜你喜欢
    • 2014-03-30
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多