You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Bootstrap Row点击事件冒泡致Offcanvas无法关闭

问题根因

这是DOM事件冒泡导致的状态异常:

  • 你将InspectSideDrawer(即Offcanvas组件)直接写在了绑定了onClick事件的<Row>标签内部,虽然Offcanvas是fixed定位、视觉上浮在页面上层,但DOM节点仍然属于<Row>的子元素。
  • 点击Offcanvas头部关闭按钮时,点击事件会沿DOM树向上冒泡,在触发closeInspectCanvas将状态设为false后,事件会继续冒泡到外层<Row>,触发绑定的showCanvas方法,立刻把状态重新设为true,最终表现为Offcanvas无法关闭。
  • 你测试将点击事件绑定在<Button>上无异常,本质是当时测试场景下浮层组件没有作为Button的子元素渲染,事件冒泡路径不会触发Button的点击逻辑。
解决方案

以下两种方案选其一即可,优先推荐方案2,逻辑更干净。

方案1:拦截事件冒泡

在关闭逻辑中调用事件对象的stopPropagation方法,阻止点击事件继续向上冒泡到<Row>。
修改父组件的关闭方法:

const closeInspectCanvas = (e) => {  
    console.log("Triggering close canvas...")
    // 阻止事件向上冒泡
    e?.stopPropagation()
    setInspectCanvasShow(false)
    console.log("Triggering close canvas done")
}    

这个方案改动最小,但要注意如果后续给Offcanvas加了其他可点击的交互元素,都需要额外处理冒泡逻辑,否则还是会出现同类问题。

方案2:调整DOM结构,将Offcanvas移出触发容器

把InspectSideDrawer组件从<Row>内部移到外层,和<Row>平级渲染,从结构上切断事件冒泡的路径,这也是浮层类组件的常规编写方式。
修改父组件的返回结构:

return (
    <>
        <Row 
            className="mx-0 my-3 p-3 cst-inspect-transaction-card"
            onClick={()=>showCanvas()}
        >
            <Col className="px-0 d-flex flex-column justify-content-between">
                <small>
                    <h6 className="">#NAS9DU239</h6>
                </small>
                <small className="d-flex align-items-center text-secondary">
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="gray" className="bi bi-calendar" viewBox="0 0 16 16">
                        <path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>
                    </svg>
                    <span className="mx-1">10 May 2022</span>
                </small>
            </Col>
            <Col className="px-0 d-flex flex-column justify-content-between">
                <div className="text-end">
                    <h6>Status:
                        <span className="cst-text-highlight-blue"> Checking</span>
                    </h6>
                </div>
                <div className="text-end text-secondary">
                    <small>Po No:
                        <span> 01229527071243248</span>
                    </small>
                </div>
            </Col>
        </Row>
        {/* Offcanvas移到Row外平级渲染 */}
        <InspectSideDrawer
            inspectCanvasShow={inspectCanvasShow}
            closeInspectCanvas={closeInspectCanvas}
        />
    </>
)

这个方案不需要额外写事件拦截逻辑,后续给Offcanvas加任何交互都不会触发外层Row的点击事件,可维护性更好。


内容的提问来源于stack exchange,提问作者suryanto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:18:21