user11680003
user11680003

Reputation:

Unmounted components still being rendered first

I'm new to React, just a question on componentWillUnmount() and render() lifecycle method. Below is some code:

...
export default class App extends Component { 
   constructor(props) {
      super(props);
      this.state = { showMessage: true }
   }
 
   handleChange = () => { this.setState({ showMessage: !this.state.showMessage });
 }
   
   render(){
      <div>
         <input type="checkbox" checked={ this.state.showMessage } onChange={ this.handleChange } />
         <label>Show</label>
     </div>
     { this.state.showMessage && <Message message="Hello" /> }
   }
}

export class Message extends Component {
   ...
   componentWillUnmount() { 
      console.log("Unmount Message Component");
   }

   render(){
      console.log(`Render Message Component `);
      return (
         <div>{this.props.message}</div/
      )
   
   }
}

I trigger the unmounting phase of the Message componentby unchecking the checkbox , so I have those in the console output:

Render Message Component

Unmount Message Component

so my question is:

It is not efficient because the current Message component is going to be destroyed since I don't need it once I uncheck the box. But Message component's render() was still being called, which is unnecessary since we don't really care what content it contains, is it a way to avoid the call of re-render method and just get componentWillUnmount() to be called? I was thinking to use shouldComponentUpdate(), but I can stop render() method to be called, but that will also stop componentWillUnmount() to be called too

Upvotes: 0

Views: 50

Answers (1)

marzelin
marzelin

Reputation: 11600

When you unmount a component render is not executed - only componentWillUnmount is called. The Render Message Component log is caused by initial render when Message is visible:

class App extends React.Component { 
   constructor(props) {
      super(props);
      this.state = { showMessage: true }
      console.log("initial render:");
   }

   handleChange = () => { this.setState({ showMessage: !this.state.showMessage });
 }

   render(){
      this.state.showMessage || console.log("unmounting:");
      return <div>
         <input type="checkbox" checked={ this.state.showMessage } onChange={ this.handleChange } />
         <label>Show</label>
         { this.state.showMessage && <Message message="Hello" /> }
     </div>
     
   }
}

class Message extends React.Component {
   componentWillUnmount() { 
      console.log("Unmount Message Component");
   }

   render(){
      console.log(`Render Message Component `);
      return (
         <div>{this.props.message}</div>
      )

   }
}

ReactDOM.render(<App/>, document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.development.js"></script>
<div id="root"></div>

Upvotes: 2

Related Questions