how to remove / unmount nested react components
Asked Answered
S

2

6

I'd like to unmount a single react component, which belongs to a parent component containing three components total. The parent component has this render function:

render: function () {
  return (
    <div className={classes}>
      <Navbar ref="navbar"/>
      <Home ref="home"/>
      <Footer ref="footer"/>
    </div>
),

handleNavbarClick: function () {
  // remove Home
}

if a user then clicks on a link in the navbar and I want to unmount the Home component, how would I do that? it seems like my only option is to do something like this (taken from react.js: removing a component), but this seems pretty gross:

render: function () {
  var home = this.state.remove_home ? null : <Home ref="home />
  return (
    <div className={classes}>
      <Navbar ref="navbar"/>
      {home}
      <Footer ref="footer"/>
    </div>
),

handleNavbarClick: function () {
  this.setState({remove_home: true});
}

Is that the appropriate react way to do things?

Semifluid answered 26/5, 2015 at 0:43 Comment(0)
H
4

Yes, your proposed solution of

render: function () {
  var home = this.state.remove_home ? null : <Home ref="home" />
  return (
    <div className={classes}>
      <Navbar ref="navbar"/>
      {home}
      <Footer ref="footer"/>
    </div>
),

handleNavbarClick: function () {
  this.setState({remove_home: true});
}

is more-or-less the "correct" way to handle this with React. Remember, the purpose of render is to describe the way your component should look at any given point. Reaching out to the DOM and performing manual operations, or doing other kind of imperative work like "removing" an element, is almost always the wrong thing to do.

If you're concerned about the syntax, you can consider inlining or extracting the logic:

render: function () {
  return (
    <div className={classes}>
      <Navbar ref="navbar"/>
      {this.state.remove_home ? null : <Home ref="home" />}
      <Footer ref="footer"/>
    </div>
),

or

render: function () {
  return (
    <div className={classes}>
      <Navbar ref="navbar"/>
      {!this.state.remove_home && <Home ref="home" />}
      <Footer ref="footer"/>
    </div>
),

or

render: function () {
  return (
    <div className={classes}>
      <Navbar ref="navbar"/>
      {this.renderHome()}
      <Footer ref="footer"/>
    </div>
),

renderHome: function() {
  if (!this.state.remove_home) {
    <Home ref="home" />
  }
}
Hashim answered 26/5, 2015 at 2:56 Comment(1)
thanks. I like the idea of breaking out renderHome into its own functionSemifluid
E
0

try this

handleNavBarClick: function(){
    React.findDOMNode(this.refs.home).style.display = 'none';
}
Epicalyx answered 26/5, 2015 at 2:24 Comment(1)
mmm yeah that would work except the component's listeners would remain intact.Semifluid

© 2022 - 2024 — McMap. All rights reserved.