关于react.js:通过一道题来看React事件模型

上面代码输入什么

const MainApp = () => {
  const parentRef = useRef();
  const childRef = useRef();
  const parentClickFun = useCallback(() => {
    console.log('react parent');
  }, []);
  const childClickFun = useCallback(() => {
    console.log('react child');
  }, []);
  useEffect(() => {
    document.addEventListener('click', () => {
      console.log('document');
    });
    parentRef.current?.addEventListener('click', () => {
      console.log('dom parent');
    });
    childRef.current?.addEventListener('click', () => {
      console.log('dom child');
    });
  }, []);
  return (
    <div ref={parentRef} onClick={parentClickFun}>
      <div ref={childRef} onClick={childClickFun}>
        事件执行程序
      </div>
    </div>
  );
};

执行后果:

  • dom child
  • dom parent
  • react child
  • react parent
  • document

    代码剖析

次要是考查 React 合成事件和 JS 原生事件的区别,以及它们的执行程序。以React16.x版本之前的来剖析。React16.x 当前有变更。
剖析一下下面的代码:能够分成两局部来看,JS原生事件局部及React合成事件局部。

  • useEffect 外面都是间接通过 addEventListener 做的事件绑定,如果addEventListener 不指定第二个参数的话,默认是冒泡阶段执行。所以 useEffect里的执行程序 dom child, dom parent, document
  • 再来看 parentClickFun, childClickFun 这两个函数是通过 React 的事件去绑定的。React 利用事件委托机制在 document 上对立监听DOM事件,再依据触发的target将事件散发到具体的组件实例。React 本人实现了一套冒泡机制。所以这部分的执行程序为:react child,react parent

最初来了解一下整个的执行程序。

  • react中的所有事件都是挂载到document上的
  • 当实在 dom 触发冒泡到 document 后才会对react事件进行解决
  • 所以JS原生事件会先执行
  • 而后执行React的合成事件
  • 最初执行真正挂载到 document上的事件

更多能够查看上面提到的文章

参考

  • 【React深刻】React事件机制
  • React17 事件零碎 更改 & 16 之前事件零碎介绍

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理