Destroy React Component (Unmounting Component)

Asked

Viewed 3,545 times

2

I would like to know how to destroy a component with React by clicking a button. I found a way out, but in my conception it is quite "gambiarrosa". I have a state called show and when click on close change the value of this.state.show to false, in the render() method I use a ternary if to render the component or not depending on the value this.state.show.

Mycomponent.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import FontAwesome from 'react-fontawesome';

class MyComponent extends Component {

  constructor(props) {
    super(props);
    this.state = {
      show:true,
    };
  }

  closeComponent(){
      console.log("Destruir componente");
      var x = ReactDOM.findDOMNode(this);
      console.log(x);
      //ReactDOM.unmountComponentAtNode(this.container);
      this.setState({ show: false });
  }

  componentDidMount() {
  }

  componentWillUnmount() {
    clearInterval(this.state);
  }

  render() {
    return (
      this.state.show ?
      <div className="MyComponent">
        <h1>Mostrar componente</h1>
        <FontAwesome name="window-close-o" onClick={this.closeComponent.bind(this)}/>
      </div>
      : null
    );
  }

}

export default MyComponent;

This is really the only way out for what I need to do?

Componentfather.js

import React, { Component } from 'react';
import './ComponentFather.css';
import MyComponent from '../MyComponent/MyComponent'

class ComponentFather extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: "Adicionar Categoria",
      key: 0,
      matchs: [],
    };
  }

  componentDidMount(){

  }

  componentWillUnmount(){
    clearInterval(this.state);
  }

  buttonClicked(){
    var mat = this.state.matchs;
    this.state.key ++;
    mat.push(<Match key={this.state.key}/>);
    console.log(mat);
    this.setState({
      matchs: mat
    });
  }

  render() {
    return (
      <div className="ComponentFather">
        <h1>Events Information</h1>
        <MyComponent></MyComponent>
        <MyComponent></MyComponent>
        <MyComponent></MyComponent>
      </div>
    );
  }
}

export default ComponentFather;

Maincomponent

import React, { Component } from 'react';
//import logo from './logo.svg';
import './App.css';
import ComponentFather from '../ComponentFather/ComponentFather';
import Streaming from '../Streaming/Streaming';

//import {Grid, Row, Col, Clearfix} from 'react-bootstrap';

class App extends Component {
  render() {
    return (
      <div className="App">
        <ComponentFather />
        <Streaming />
      </div>
    );
  }
}

export default App;

index js.

import React from 'react';
import ReactDOM from 'react-dom';

import App from './components/App/App';

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap/dist/css/bootstrap-theme.css'

ReactDOM.render(
  <App />,
  document.getElementById('main-container')
);
  • 1

    I just saw your Dit. Give me an idea that your code is adapted and not the real code. Two questions: These MyComponent are always 3 or is it dynamic? Another question, the ComponentFather knows the state of each MyComponent?

  • I’ve got all three tied up just to have a representation of what it’s gonna be like, but the right thing is to be dynamic. As for your other question, I don’t know the answer. I started the studies in React these days, devouring the documentation to see if it clears things up more. The idea is this, the Componentfather will load a list of objects from the backend and for each object in the list I will create a Mycomponent passing the object as parameter, the properties of the object will all be displayed in Mycomponent and within Mycomponent I will have the option to destroy that component by clicking on a given button....

  • Okay. If the ComponentFather keep the state of each MyComponent he will know whether or not to show a given MyComponent. This seems to me the right way. Are you using Flux? Mobx? None of them? Soon I will give an example to see if this is what you are looking for

  • For now I am only in the static part but I want to use Flux, so I have read the most viable. But I have to dig a little deeper because the communication will be via socket. From what I saw in your answer that’s exactly what I need. Thank you so much for the strength you’re giving me. Just one more thing... Is there any material you recommend to boost my learning around React?

  • Take a look here however: https://www.youtube.com/watch?v=Wsg3aSvPCXE

  • One more question for the example I’m setting: these MyComponent are a representation of what? an array? a BD list? keys of an object?

  • Keys to an object

  • I edited the answer, how you’re doing it works well. Depending on the logic of the parent element you can have an array with child elements not render via "parent", but as you have it works well. Take a look at my jsFiddle, it may be useful for testing.

Show 3 more comments

1 answer

3


The way to disassemble a component is with ReactDOM.unmountComponentAtNode. This method accepts the DOM element on which the component is mounted. If you do not have an element reference you can pass ReactDOM.findDOMNode(this).parentNode as an argument.

So your method of destroying the component could be:

closeComponent() {
    console.log("Destruir componente");
    var container = ReactDOM.findDOMNode(this).parentNode;
    ReactDOM.unmountComponentAtNode(container);
}

If this component is inserted in another, it would be best to hide the element via parent component. Depending on the logic behind the state of the component.

In your case, how you’re doing is valid, so the component MyComponent is responsible for guarding its own state. And it would look like this: https://jsfiddle.net/5gjapobx/

  • It did not... Warning.js:36 Warning: unmountComponentAtNode(): The Node you’re attempting to unmount was rendered by React and is not a top-level container. Instead, have the Parent Component update its state and rerender in order to remove this Component.

  • @Lukssys thought it was an isolated component, so I need you to show the component where it’s inserted to help...

  • I will edit the code above and show the code where it is inserted

  • 1

    Thanks for your help, you solved my problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.