react事件按照组件树传播

22 阅读1分钟

某天 写了这样一个组件 真的只是顺手 我平常不这么写的

      <Button onClick={() => setOpen(true)}>
        按钮
        <Modal open={open} onCancel={() => setOpen(false)}>
        </Modal>
      </Button>

然后发现这个弹窗关不掉了
由于知道Modal的dom并不在整个项目的根节点下,所以一开始只是以为函数写的有问题或者属性名写错了.在onCancel和组件函数里都加了console,发现onCancel正常执行,组件也正常更新,我意识到事情并不简单(不过也没有那么复杂).
我把目光投向Button上面那个唯二的setOpen,把它删掉,把open初始值设为true,弹窗就可以正常关闭了.所以上述bug出现的原因是点击关闭icon不仅触发onCancel,还触发onClick,这个事件冒泡至Button,触发其onClick,导致open值保持true.尽管open值不变,但onCancel中setOpen(false)还是会导致组件更新.
通过这个bug 复习一下知识点:react合成事件也具有捕获和冒泡阶段,按照组件树传播,与组件实际的挂载位置无关