在 ReactJS 中显示/隐藏组件

Posted

技术标签:

【中文标题】在 ReactJS 中显示/隐藏组件【英文标题】:Show/Hide components in 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 '' 的错误 【参考方案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();

  



【讨论】:

以上是关于在 ReactJS 中显示/隐藏组件的主要内容,如果未能解决你的问题,请参考以下文章

reactjs - 如何隐藏一个div并将其替换为reactjs中的另一个div?

ReactJS 中的参数路由不显示 UI 组件

ReactJS 组件中显示的视频未更新

ReactJs:根据选择值显示或隐藏输入字段

如何在所有页面(所有组件)ReactJs 中显示类似用户名的属性? [复制]

带有 Redux 的 ReactJS 在 SVG 组件上显示引导工具提示