blankface
blankface

Reputation: 6347

Unmounting a React component the correct way

export class Child extends React.Component{
  unmount() {
    const node = ReactDOM.getDOMNode(this);
    ReactDOM.unmountComponentAtNode(node );
}

  render() {
    return <button onClick={this.unmount.bind(this)}>Unmount</button>
  }
}

For the above sample component, would it possible to unmount it on click using unmountComponentAtNode?

Upvotes: 4

Views: 25746

Answers (2)

Maciej Sikora
Maciej Sikora

Reputation: 20132

React application is always a components composition, or in different words - components tree. It means that every component has parent component, which renders it, it is only falsy statement for root component, mostly we name it App, but we do not talk about it in that question. Above all, we can say that a component, which needs to be unmounted, always has a parent component.

As we did the assumption in first paragraph, the correct way of unmounting React component is to remove it from render method in parent component. It can be done in many ways, the simplest is just an conditional component rendering like:

class IAmParentComponent extends React.Component {
  render() {
    return (<div>{this.state.show && <YourChildComponentToUnmount/>}</div>)
  }
}

Above example shows IAmParentComponent as container component which holds a state, and the YourChildComponentToUnmount will render if this.state.show is true, will unomount after state change from true to false.

Back to your code with callback, the callback should be send into component by props, and the parent component should do the state change related to removing the component from render tree, what exactly will start unmount phase of the component, and finally component will be removed from UI.

In conclusion, component unmount should be in responsibility of component above it, component should not unmount itself.

Upvotes: 4

Guillermo Quiros
Guillermo Quiros

Reputation: 441

This is not the way react. The best way to unmount an element is to tell the parent to remove the child from the rendered children of the parent.

Look at this example. Here we have the CardContainer class and CardItem class.The CardItem item class has a delete self button. This method send an event to the parent container to remove itself from the rendered children.

    const carddata = [
      {key:1 ,name: 'Card A',visible:true},
      {key:2 ,name: 'Card B',visible:true}
    ];

    class CardItem extends React.Component {
    constructor(props){
        super(props)
        this.handleClick=this.handleClick.bind(this);
    }
    componentWillUnmount(){
        console.log('unmount')
    }
    handleClick(){
        this.props.destroy(this.props.id)
    }
    render(){
        return(<div>
                Card 
                <button onClick={this.handleClick} >delete</button>
                </div>)
    }

  }

  class CardContainer extends React.Component {
    constructor(props){
        super(props)
        this.state = {data: carddata};
        this.destroy = this.destroy.bind(this);
    }
    destroy(elementKey){
        console.log(elementKey)
        debugger
        let result = this.state.data.filter(item=> item.key !==elementKey);
        this.setState({data: result});

    }

    render(){

          return (<div>
                  Card Container
                  {this.state.data.map((card,index) => {
                    return <CardItem key={card.key} id={card.key} name={card.name} destroy={this.destroy}/>
                    })
                  }
                 </div>)
    }

  }

Upvotes: 1

Related Questions