上面代码输入什么
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 之前事件零碎介绍