如何实现点击按钮将React函数式组件从DOM中卸载
函数式组件点击卸载实现方案
React 组件没有独立卸载自身的能力,卸载的本质是上层渲染逻辑不再返回该组件,根据你的使用场景选对应实现即可:
场景1:组件作为子组件嵌套在其他组件内(常规开发场景)
这是官方推荐的标准实现方式,由父组件持有渲染控制状态,将卸载方法通过props传递给子组件绑定触发:
- 父组件实现状态控制逻辑
import { useState } from 'react' import App from './App' function Parent() { // 控制子组件渲染的开关,默认true显示组件 const [isMounted, setIsMounted] = useState(true) return ( <div className="container"> {/* 开关为true时才渲染目标组件,false时直接不返回对应JSX,即完成卸载 */} {isMounted && <App unmount={() => setIsMounted(false)} />} </div> ) } export default Parent
- 修改你现有的App组件,接收unmount参数绑定到按钮点击事件
import React from 'react' function App({ unmount }) { return ( <div className='app-component'> <h2 className="h2">App Component</h2> <button onClick={unmount}>Unmount This Component</button> </div> ) } export default App
这种实现下,组件内部所有useEffect返回的清理函数(定时器清除、事件解绑、订阅取消等)都会在卸载时正常执行,不会产生内存泄漏。
场景2:组件是挂载在根节点的入口组件
如果你的App是整个应用的根组件,直接挂载到public/index.html的根DOM节点上,可以直接调用React提供的根节点卸载方法,不需要父组件传参,注意区分React版本:
React 18+ 版本
入口文件通常会先创建root实例再渲染组件:
// 入口文件main.jsx/index.jsx import { createRoot } from 'react-dom/client' import App from './App' const root = createRoot(document.getElementById('root')) root.render(<App root={root} />)
修改App组件调用root实例的unmount方法:
import React from 'react' function App({ root }) { return ( <div className='app-component'> <h2 className="h2">App Component</h2> <button onClick={() => root.unmount()}>Unmount This Component</button> </div> ) } export default App
React 17 及更早版本
旧版本使用unmountComponentAtNodeAPI实现,直接传入挂载的DOM节点即可:
import React from 'react' import ReactDOM from 'react-dom' function App() { const handleUnmount = () => { const mountNode = document.getElementById('root') ReactDOM.unmountComponentAtNode(mountNode) } return ( <div className='app-component'> <h2 className="h2">App Component</h2> <button onClick={handleUnmount}>Unmount This Component</button> </div> ) } export default App
注意:根节点直接卸载的方式仅适用于整个应用完全退出的场景,日常业务开发中嵌套的子组件不要用这种方式绕过React自上而下的状态流,否则会引发状态不同步的问题。
内容的提问来源于stack exchange,提问作者Ren Jitsm
相关产品推荐
相关产品推荐

