react教程,如何卸载一个根组件或子组件?root.unmount()
发布于 作者:苏南大叔 来源:程序如此灵动~

首先,react
可不可以主动卸载一个根组件?肯定是可以的,react
必然有这个能力从根源上卸载。那换成卸载子组件呢?那么,也必须是有这个能力的。那么,如何卸载这个根组件或者子组件呢?这就是本文中要探讨的问题。

苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。测试环境:create-react-app@5.0.1
,react@18.2.0
,react-dom@18.2.0
,node@16.14.2
。
测试标的组件
苏南大叔的目标是这样的:
1、使用react
的方式卸载组件,而不是通过html
操作dom
的方式来实现这个需求。
2、卸载组件的时候,希望能够把关联的dom
元素也一并卸载。比如利用传送门脱离原有体系的组件。

测试组件:
有关传送门组件的定义:
https://newsn.net/say/react-portal.html
方案一,.parentNode.removeChild()
首先需要肯定的是:react
最终也是在页面上形成了传统的元素节点。所以,使用.removeChild
的方式,是必然可以删除节点的。但是,这操作超出了react
的概念。附加在被删除节点上的ref
或者state
之类的数据,可能会造成一些问题。
或者
原理上就是使用真实节点的父节点来删除对应真实节点。所以,它必然可以生效,但是也必然必能关联删除附加节点(比如传送门生成的节点)。

方案二,root.unmount()
/root.render("")
这个方案仅仅针对根组件root
生效,是无法控制子组件的。而root
一般是通过props.root
从最外层传递进来的变量,例如:
这样的话,在<App/>
内部,就可以通过props.root
来进行整体组件卸载了。两种方式:
或者

ReactDOM.unmountComponentAtNode(真实dom)
,在最新的react@18
系列中已经不存在这个函数了。
方案三,.createRoot().unmount()
/.createRoot().render("")
这个方案可以处理子组件,但是不能处理根组件root
。原理上来说,上一个方案中的root
是已经被.createRoot()
过的。已经被处理过的.createRoot()
不能再次被处理,这也是root
不能使用本方案的原因。
这个方案原理就是把子组件的真实dom
,变成一个react
的根组件,然后再unmount()
或者render("")
,达到卸载子组件的目的。现在假设真实dom
是个className
为aaa
的子组件。
或者

虽然这个方案能够达到目的,但是苏南大叔总是感觉哪里不对劲。这个函数的结果并不像是对原来的组件进行卸载,而且对原结构进行了破坏...
方案四,state && <组件/>
【推荐】
苏南大叔认为:react
和传统的页面逻辑的区别就在于:行动的主动权在谁手里。不同于传统页面,react
更像是一种自发式的组织形式,并没有谁能够主动掌控组件的生死。所以从react
的方式来思考问题的话,主动卸载某个组件的函数是不是理论上不存在啊...
那么,以react
的思路来解释这个需求的话。苏南大叔认为:完美方案就是state && <组件/>
。当不想要这个组件的时候,就切换一下state
即可。对应组件就会被卸载,而不是隐藏。

测试代码
以下是本文的完整测试代码:
结束语
从react
的角度来想这件事情的话,本文中的这个需求的大部分内容可能是个伪需求。因为主动让某个东西做某事,这并不符合react
的思路,更优的思路是:根据某个状态或情形,组件自己主动做某事。驱动力来自自身,而非外界强迫。


