• 【React】unmountComponentAtNode卸载组件


    unmountComponentAtNode这个方法,并不陌生。

    官方给出的解释是:

    从 DOM 中卸载组件,会将其事件处理器(event handlers)和 state 一并清除。如果指定容器上没有对应已挂载的组件,这个函数什么也不会做。如果组件被移除将会返回 true,如果没有组件可被移除将会返回 false。

    虽然在 React18 中,它已被 root.unmount() 取代。 但这不重要,项目目前的版本我也升不上去(历史原因)。

    没想到,这两天还在这里栽了跟头,头大。

    为什么这么说呢?看看下面的例子就明白了。

    正常来说,unmountComponentAtNode只会对ReactDOM.render挂载在顶层的元素进行卸载。

    效果看图:
    ​​在这里插入图片描述
    root下面有一个div,点击卸载组件按钮之后,root下面的div不见了,说明卸载成功了。

    具体代码如下:

    // index.js
    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    
    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById('root')
    );
    
    // App.js 
    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Button } from 'antd';
    
    const App = () => {
      // 新增Dom
      const addDom = () => {
        const div = document.createElement('div');
        div.innerHTML = '不可卸载组件'
        document.getElementById('root').appendChild(div);
      }
      // 销毁组件
      const destory = () => {
        ReactDOM.unmountComponentAtNode(document.getElementById('root'));
      }
      return (
        <div>
          可卸载组件
          <Button type="primary" style={{ margin: '0 8px'}} onClick={destory}>卸载组件</Button>
          <Button type="primary" onClick={addDom}>新增DOM</Button>
        </div>
      )
    }
    
    export default App;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    那如果我新增一个dom节点,并且该节点并不是直接放在ReactDOM.render里渲染的,而是通过appendChild插入到root下的。这个节点在我卸载root的时候,会被卸载掉吗?

    实际操作如下:
    在这里插入图片描述
    很明显,卸载不成功。这也是我踩坑的地方,如果想要插入的元素也被卸载掉,可以插入到App.js的节点中,不要直接插入到根节点。

    总之,unmountComponentAtNode只对ReactDOM.render挂载在顶层的组件才生效,其余无关render方法永远返回的都是false

    最后,附上React18的版本(效果同上):

    // index.js
    import { createRoot } from 'react-dom/client';
    import App from './App';
    
    const container = document.getElementById('root');
    const root = createRoot(container);
    root.render(<App root={root} />);
    
    // App.js
    import React from 'react';
    import { Button } from 'antd';
    
     const App = (props) => {
      const { root } = props;
      // 新增Dom
      const addDom = () => {
        const div = document.createElement('div');
        div.innerHTML = '不可卸载组件'
        document.getElementById('root').appendChild(div);
      }
      // 销毁组件
      const destory = () => {
        root.unmount();
      }
      return (
        <div>
          可卸载组件
          <Button type="primary" style={{ margin: '0 8px'}} onClick={destory}>卸载组件</Button>
          <Button type="primary" onClick={addDom}>新增DOM</Button>
        </div>
      )
    }
    
    export default App;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    Mysql调优你不得不考虑的事
    ceph delete pool
    Pan-cancer image-based detection of clinically actionable genetic alternations
    【Python】pdf转ppt
    微信小程序自动化采集方案
    GWD:基于高斯Wasserstein距离的旋转目标检测 | ICML 2021
    Spring 源码阅读:用于创建 AOP 代理的后处理器分析
    【BOOST C++】高级01 RAII和内存管理
    Debian 初始化命令备忘
    力扣labuladong——一刷day07
  • 原文地址:https://blog.csdn.net/weixin_38629529/article/details/126554759