react.js: removing a component
Asked Answered
H

3

35

I'm fairly new at react.js, so any help is greatly appreciated.

I have this: https://jsfiddle.net/rzjyhf91/

Wherein I have made 2 components: an image and a button.

The goal is to remove the image with a click of the button, I use unmountComponentAtNode for that, but it does not work:

var App = React.createClass({
  render: function() {
    return (
    <div><MyImage /><RemoveImageButton /></div>
    );
  }
});

var MyImage = React.createClass({
  render: function() {
    return (
      <img id="kitten" src={'http://placekitten.com/g/200/300'} />
    );
  }
});

var RemoveImageButton = React.createClass ({
  render: function() {
    return (
      <button onClick={this.handleClick}>remove image</button>
    )
  },
  handleClick: function(){
    React.unmountComponentAtNode(document.getElementById('kitten'));   
  }
});

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

How can I remove a react component from another component?

Hartnett answered 1/12, 2014 at 11:49 Comment(2)
wow, this seems to be a bug... you should have done something like this: <div><div id="someid"><MyImage /></div><RemoveImageButton /></div> and then unmount on the "someid"... but this doesnt work either. I think you would have to forceUpdate() the App component or something...Featheredge
I don't know the answer, but I would set the image as the state of the App, and then change/remove the state's value which triggers a re-render.Caudle
F
48

Well, it seems you should rethink how the display control is handled. React is all about isolated components, and so, you shouldn't be unmounting a component that is mounted by a parent component. Instead, you should use a callback passed down through props to accomplish something like that.

Your actual implementation will depend on your use case, but an updated version of your example that works is at: https://jsfiddle.net/nt99zzmp/1/

var App = React.createClass({
  render: function() {
    var img = this.state.showImage ? <MyImage /> : '';
    return (
    <div>{img}<RemoveImageButton clickHandler={this.removeImage} /></div>
    );
  },
  
  getInitialState: function() {
      return {
          showImage: true
      };
  },
  
  removeImage: function() {
      this.setState({ showImage: false });
  }
});

var MyImage = React.createClass({
  render: function() {
    return (
      <img id="kitten" src={'http://placekitten.com/g/200/300'} />
    );
  }
});

var RemoveImageButton = React.createClass ({
  render: function() {
    return (
      <button onClick={this.props.clickHandler}>remove image</button>
    )
  }
});

React.render(<App />, document.body);
Forgotten answered 1/12, 2014 at 19:49 Comment(1)
Thank you so much, this helps me greatly in my understanding of structuring code!Hartnett
D
7

Basically removing a component doesn't make sense in React, you probably still thinking jQuery ways, basically in all modern and new JavaScript libraries including React, you should manage your component using state or a route to handle these things, deleting an element or component is not a good way to do these things in React or Angular for example.

For example you can have a boolean in this case and if it's true, show your image, otherwise hide it, or even return a different element in your component.

enter image description here

So in this case, you have a component which will return differently depends on props or state... something like this:

////
var MyImage = React.createClass({
  render: function() {
    if(this.state.showImage) {
      return (
        <img id="kitten" src={'http://placekitten.com/g/200/300'} />
      );
    } else {
      return<p>no image!</p>;
    }
  }
});
////
Dorison answered 13/6, 2017 at 12:51 Comment(0)
L
6

In this example, if you set this.state.render = false, the component will be removed from DOM:

  render() {
    const { render } = this.state;
    if (render === false) return null;
    return (<p>I am here as long as render isn't false</p>);
  }
Lacedaemonian answered 28/6, 2018 at 15:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.