React 中是如何处理事件的,现在下面简单的一段代码:
export default function App() {
const AList = lazy(()=>import('./List.js'))
const r = useRef(null)
const [show, setShow] = useState(false);
return (
<>
<button onFocus={()=>{
setShow(!show)
}} >加载组件</button>
{show ?
<Suspense fallback="loading">
<AList items={[{id:1, text:"123"}]}>asdf</AList>
</Suspense>
:""}
</>
);
}
代码为 Button 绑定了 onFocus 事件,这里用 onFocus 是为了方便 debug。如果做一个框架要接管所有的事件处理,我们想一下应该如何处理,可以通过代理的方式,把所有可以监听到的事件交给代理去处理,最后在交给框架组件上绑定的对应事件进行处理。由于 JS 是冒泡事件模型,所有事件都会向上传递,只要监听最顶层容器就可以监听到所有事件,当点击发生的时候调用目标组件绑定的事件。
我们看一下,React 中怎么处理的。
组件注册事件
创建 Element,添加 props,这个 props 中就是 Focus 方法,将最终方法于 Element 绑定并包存在 Fiber 上。
绑定代码
Root 代理所有事件
创建 Root 时会监听所有事件:
方法中 loop 所有 Html 原生事件
事件触发
Focus 事件触发时,会执行 dispatchDiscreteEvent 方法,这个方法在 Root 代理监听时进行的绑定。
获取组件事件处理方法,这个方法在组件创建时进行的绑定。
总结
React 事件机制是一个代理模式,所有处理都由根组件监听并进行分发处理。