이 글에서 공유한 내용은 React 이벤트 시스템 분석에 관한 내용으로, 도움이 필요한 친구들이 참고할 수 있습니다.
React 이벤트 시스템에는 합성 이벤트와 네이티브 이벤트의 두 가지 유형이 있습니다.
React 컴포넌트를 작성할 때 합성 이벤트를 바인딩하는 것은 쉽지만, 다른 컴포넌트의 합성 이벤트를 하나의 컴포넌트에 바인딩할 수 있는 방법은 없습니다. 이때 네이티브 이벤트가 유용합니다.
혼합(합성 이벤트와 네이티브 이벤트의 혼합) 이벤트에 대해 이야기하는 것 외에도 이벤트 버블링도 자주 다루어야 하는 문제입니다. 이번 글에서는 이를 React와 함께 소개하겠습니다.
1-1. React는 Virtual DOM을 기반으로 한 SyntheticEvent(합성 이벤트) 레이어를 구현하며 SyntheticEvent 객체의 인스턴스도 지원합니다. 버블링 메커니즘을 사용하면 stopPropagation() 및 PreventDefault()를 사용하여 이를 중단할 수 있습니다.
1-2. 모든 이벤트는 자동으로 가장 바깥쪽 레이어(문서)에 바인딩됩니다.
React 하단에는 합성 이벤트에 대해 수행되는 두 가지 주요 작업이 있습니다: 이벤트 위임 및 자동 바인딩.
2-1. 이벤트 위임
React 이벤트를 사용하기 전에 이벤트 위임 메커니즘을 숙지해야 합니다. 이벤트 처리 기능을 실제 노드에 직접 바인딩하지 않고 모든 구성 요소 내부에 이벤트 수신 및 처리 기능을 저장하는 통합 이벤트 리스너를 사용하여 모든 이벤트를 구조의 가장 바깥쪽 레이어에 바인딩합니다. 구성 요소가 마운트되거나 마운트 해제되면 일부 개체가 이 통합 이벤트 리스너에 삽입되거나 삭제됩니다. 이벤트가 발생하면 먼저 이 통합 이벤트 리스너에 의해 처리된 다음 실제 이벤트 처리 함수가 매핑에서 발견되고 호출됩니다. . 이는 이벤트 처리 및 재활용 메커니즘을 단순화하고 효율성을 크게 향상시킵니다. 2-2. 자동 바인딩
이를 현재 구성 요소에 자동으로 바인딩합니다
. 또한 React는 CPU 및 메모리 최적화를 달성하기 위해 이 참조를 캐시합니다. 3. React에서 기본 이벤트 사용
컴포넌트 제거 시 네이티브 이벤트
에서 로그아웃해야 합니다. 4. 합성 이벤트와 네이티브 이벤트 혼합
버블링을 방지하기 위해 ReactEvent.nativeEvent.stopPropagation()을 사용할 수는 없습니다. React 이벤트 버블링을 방지하는 동작은 React 합성 이벤트 시스템에서만 사용할 수 있으며 기본 이벤트 버블링을 방지할 수 있는 방법은 없습니다. 반대로 네이티브 이벤트에서 버블링 동작을 방지하면 React 합성 이벤트의 전파를 방지할 수 있습니다.
5.React stopPropagation 및 stopImmediatePropagation
React를 통해 바인딩된 이벤트, 콜백 함수의 이벤트 개체는 React에 의해 합성된 SyntheticEvent이며 이는 기본 DOM의 이벤트와 동일하지 않습니다. 이벤트 한 가지. 정확하게 말하면 React에서 e.nativeEvent는 기본 DOM 이벤트의 이벤트입니다.
그림에서 다음과 같은 결론을 내릴 수 있습니다.
(2) DOM 이벤트의 버블링을 방지하면 합성 이벤트도 방지할 수 있기 때문입니다. DOM 이벤트의 버블링을 방지하면 이벤트가 문서에 전파되지 않습니다.
(3) 합성 이벤트와 DOM 이벤트가 모두 문서에 바인딩되면 React의 처리는 합성 이벤트를 먼저 넣어야 하므로 이 경우 기본 이벤트인 stopImmediatePropagation이 문서 DOM 이벤트의 추가 트리거를 방지할 수 있습니다
stopImmediatePropagation: 동일한 요소에 바인딩된 동일한 유형의 이벤트 리스너 함수가 여러 개 있는 경우 해당 유형의 이벤트가 트리거되면 추가된 순서가 실행됩니다. 청취 함수 중 하나가 event.stopImmediatePropagation() 메서드를 실행하면 나머지 청취 함수는 실행되지 않습니다
(1) 합성 이벤트 간의 버블링을 방지하려면 e.stopPropagation();
을 사용하십시오. (2) 합성 이벤트가 분리되는 것을 방지하려면 레이어 문서에서 이벤트 버블링을 방지하려면 e.nativeEvent.stopImmediatePropagation();
(3)을 사용하여 가장 바깥쪽 문서를 제외한 합성 이벤트 및 네이티브 이벤트의 버블링을 방지합니다. e. target 방지하기 위한 코드는 다음과 같습니다:
componentDidMount() { document.body.addEventListener('click', e => { if (e.target && e.target.matches('p.code')) { return; } this.setState({ active: false, }); }); }
7-1 이벤트 등록
이벤트 등록은 문서 노드, React 이벤트를 DOM 네이티브 이벤트로 변환하고 콜백을 등록합니다.
// enqueuePutListener 负责事件注册。 // inst:注册事件的 React 组件实例 // registrationName:React 事件,如:onClick、onChange // listener:和事件绑定的 React 回调方法,如:handleClick、handleChange // transaction:React 事务流,不懂没关系,不太影响对事件系统的理解 function enqueuePutListener(inst, registrationName, listener, transaction) { ... ... // doc 为找到的 document 节点 var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument; // 事件注册 listenTo(registrationName, doc); // 事件存储,之后会讲到,即存储事件回调方法 transaction.getReactMountReady().enqueue(putListener, { inst: inst, registrationName: registrationName, listener: listener }); }
이벤트 등록의 구체적인 코드와 DOM 네이티브 이벤트를 문서에 바인딩하는 방법을 살펴보겠습니다.
// 事件注册 // registrationName:React 事件名,如:onClick、onChange // contentDocumentHandle:要将事件绑定到的 DOM 节点 listenTo: function (registrationName, contentDocumentHandle) { // document var mountAt = contentDocumentHandle; // React 事件和绑定在根节点的 topEvent 的转化关系,如:onClick -> topClick var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName]; for (var i = 0; i <p>이벤트를 버블링 단계에 바인딩하기 위한 특정 코드를 살펴보겠습니다. </p><pre class="brush:php;toolbar:false">// 三个参数为 topEvent、原生 DOM Event、Document(挂载节点) trapBubbledEvent: function (topLevelType, handlerBaseName, element) { if (!element) { return null; } return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType)); } // 三个参数为 Document(挂载节点)、原生 DOM Event、事件绑定函数 listen: function listen(target, eventType, callback) { // 去除浏览器兼容部分,留下核心后 target.addEventListener(eventType, callback, false); // 返回一个解绑的函数 return { remove: function remove() { target.removeEventListener(eventType, callback, false); } } }
listen 메서드에서 마침내 익숙한 addEventListener 기본 이벤트 등록 메서드를 발견했습니다. 문서 노드에서만 이 메서드를 호출하므로 문서 노드에만 DOM 이벤트가 있습니다. 이는 DOM 이벤트 로직을 크게 단순화하고 메모리를 절약합니다.
7-2. 이벤트 저장
이벤트가 등록된 후에는 이벤트에 바인딩된 콜백 함수를 저장해야 합니다. 이런 방식으로 이벤트가 트리거된 후에만 트리거할 해당 콜백을 찾을 수 있습니다. 초기 코드에서는 putListener 메서드가 이벤트 콜백을 저장하는 데 사용되는 것을 확인했습니다.
// inst:注册事件的 React 组件实例 // registrationName:React 事件,如:onClick、onChange // listener:和事件绑定的 React 回调方法,如:handleClick、handleChange putListener: function (inst, registrationName, listener) { // 核心代码如下 // 生成每个组件实例唯一的标识符 key var key = getDictionaryKey(inst); // 获取某种 React 事件在回调存储银行中的对象 var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {}); bankForRegistrationName[key] = listener; }
7-3. 이벤트 실행
이벤트가 발생할 때마다 루트 노드에 addEventListener에 등록된 콜백이 실행됩니다. , ReactEventListener.dispatchEvent 메소드, 이벤트 배포 입력 기능입니다. 이 함수의 주요 비즈니스 로직은 다음과 같습니다:
Construct DOM 이벤트를 기반으로 하는 React 합성 이벤트.
복합 이벤트를 대기열에 넣습니다.
일괄 처리 대기열의 이벤트(이전, 선입, 첫 번째 제공 처리되지 않은 이벤트 포함)
이벤트에 의해 트리거된 DOM 및 React 구성 요소 찾기
React 구성 요소에서 findParent 메서드를 호출하고 순회하여 모든 상위 구성 요소를 가져온 후 저장합니다. 배열에서.
이 컴포넌트부터 마지막 상위 컴포넌트까지, 이전 이벤트 저장소에 따라 React 이벤트 이름 + 컴포넌트 키를 사용하여 해당 바인딩 콜백 메소드를 찾아 실행합니다. 자세한 과정은 다음과 같습니다.
React 합성 이벤트의 버블링은 실제 버블링이 아니라 노드 순회입니다.
저는 개인적으로 stopImmediatePropagation이 매우 유용하다고 생각합니다. 합성 이벤트가 DOM 문서에 올라오는 것을 방지하는 데 필요합니다.
1.合成事件本来就绑定在document上,完全可以获取这个document 2.stopImmediatePropagation可以阻止触发的document DOM上的事件,这十分有必要 3.不会阻止DOM 上的事件冒泡到document DOM
관련 권장 사항:
위 내용은 React 이벤트 시스템 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!