首页 > 解决方案 > 卸载的组件仍然首先渲染

问题描述

我是 React 的新手,只是一个关于componentWillUnmount()生命render()周期方法的问题。下面是一些代码:

...
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/
      )
   
   }
}

我通过取消选中复选框来触发组件的卸载阶段Message,所以我在控制台输出中有这些:

渲染消息组件

卸载消息组件

所以我的问题是:

它效率不高,因为当前的 Message 组件将被销毁,因为一旦我取消选中该框,我就不需要它。但是 Message 组件的 render() 仍然被调用,这是不必要的,因为我们并不关心它包含什么内容,这是一种避免调用 re-render 方法而只调用 componentWillUnmount() 的方法吗?我正在考虑使用shouldComponentUpdate(),但我可以停止调用 render() 方法,但这也将停止componentWillUnmount()被调用

标签: javascriptreactjs

解决方案


当您卸载组件时render不会执行 - 仅componentWillUnmount调用。Render Message Component日志是由Message可见时的初始渲染引起的:

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>


推荐阅读