Maison > Article > interface Web > Une analyse du système d'événements React
Le contenu partagé avec vous dans cet article concerne l'analyse du système d'événements React. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Il existe deux types de systèmes d'événements React : les événements synthétiques et les événements natifs.
Lors de l'écriture de composants React, il nous est facile de lier un événement synthétique, mais il n'existe aucun moyen de lier l'événement synthétique d'un autre composant dans un composant. Pour le moment, les événements natifs sont utiles.
En plus de parler d'événements mixtes (mélange d'événements synthétiques et d'événements natifs), le bouillonnement d'événements est également quelque chose que nous devons souvent traiter. Cet article le présentera en combinaison avec React.
1-1 React implémente une couche SyntheticEvent (événement synthétique) basée sur Virtual DOM, le gestionnaire d'événements que nous avons défini. de l'objet SyntheticEvent sera reçu, et le mécanisme de bouillonnement d'événements est également pris en charge. Nous pouvons utiliser stopPropagation() et PreventDefault() pour l'interrompre.
1-2. Tous les événements sont automatiquement liés à la couche la plus externe (document).
Au bas de React, deux choses principales sont effectuées pour les événements synthétiques : Délégation d'événements et liaison automatique.
2-1. Délégation d'événements Avant d'utiliser les événements
React, vous devez être familier avec son mécanisme de délégation d'événements. Il ne lie pas la fonction de traitement des événements directement au nœud réel, mais lie tous les événements à la couche la plus externe de la structure, en utilisant un écouteur d'événements unifié . Cet écouteur d'événements Une carte est maintenue pour stocker tous les écouteurs d'événements. et les gestionnaires au sein du composant. Lorsqu'un composant est monté ou démonté, certains objets sont simplement insérés ou supprimés sur cet écouteur d'événements unifié ; lorsqu'un événement se produit, il est d'abord traité par cet écouteur d'événements unifié, puis la véritable fonction de traitement des événements est trouvée dans le mappage et appelée. . Cela simplifie le mécanisme de traitement et de recyclage des événements et améliore considérablement l’efficacité.
2-2. Liaison automatique
Dans un composant React, le contexte de chaque méthode pointera vers l'instance du composant, c'est-à-dire la lie automatiquement au composant actuel . Et React mettra également en cache cette référence pour optimiser le processeur et la mémoire.
Les événements natifs peuvent également être utilisés sous l'architecture React. React fournit une méthode de cycle de vie complète. ComponentDidMount sera appelé une fois le composant installé et que le vrai DOM existe dans le navigateur. À ce stade, nous pouvons terminer la liaison des événements natifs.
Mais React ne gère pas automatiquement les événements natifs, vous devez donc vous déconnecter des événements natifs lors de désinstallation du composant.
C'est mentionné dans le livre (pas trop d'introduction ici) :
Ne pas mélanger événements synthétiques avec mélange d'événements natifs
Évitez-le grâce au jugement e.target
Le point clé est le paragraphe suivant, qui est également le problème que nous voulons nous concentrer sur la résolution aujourd'hui :
Utiliser réagirEvent.nativeEvent.stopPropagation() pour empêcher les bulles ne fonctionnera pas. Le comportement consistant à empêcher les événements React de bouillonner ne peut être utilisé que dans le système d'événements synthétiques React, et il n'existe aucun moyen d'empêcher les événements natifs de bouillonner. Au contraire, empêcher le comportement de bouillonnement dans les événements natifs peut empêcher la propagation des événements synthétiques React.
Mécanisme de bouillonnement d'événements :
Événements liés via React, dans leurs fonctions de rappel L'objet événement est un SyntheticEvent synthétisé par React, ce qui n'est pas la même chose que l'événement DOM natif. Pour être précis, dans React, e.nativeEvent est l'événement de l'événement DOM natif.
Diagramme de séquence d'exécution d'événements synthétiques React et d'événements natifs :
À partir du diagramme, nous pouvons tirer les conclusions suivantes :
(1) L'événement synthétique de DOM React ne sera déclenché que lorsque l'événement bouillonne dans le document, donc le e.stopPropagation de l'objet événement synthétique React ne peut qu'empêcher l'événement simulé React de bouillonner, mais ne peut pas empêcher le véritable événement DOM de bouillonner
( 2) DOM Empêcher la propagation des événements peut également empêcher les événements synthétiques. La raison en est que la prévention de la propagation des événements DOM empêche les événements de se propager au document
(3) Lorsque les événements synthétiques et les événements DOM sont liés au document, le traitement React. L'événement synthétique doit être placé en premier, il sera donc déclenché en premier. Dans ce cas, le stopImmediatePropagation de l'objet événement natif peut empêcher le déclenchement ultérieur de l'événement DOM du document
(1) Pour éviter le bouillonnement entre les événements synthétiques, utilisez e.stopPropagation(); (2) pour empêcher les événements synthétiques d'être connectés au document le plus externe. évitez le bouillonnement entre les événements, utilisez e.nativeEvent.stopImmediatePropagation();
(3) pour empêcher le bouillonnement d'événements synthétiques et d'événements natifs, à l'exception du document le plus externe. Cela peut être évité en jugeant e.target. :
componentDidMount() { document.body.addEventListener('click', e => { if (e.target && e.target.matches('p.code')) { return; } this.setState({ active: false, }); }); }7. Voir l'essence à travers le code source7-1 Enregistrement d'événement
L'enregistrement d'événement consiste à convertir les événements React en événements natifs DOM au niveau du nœud de document et à s'inscrire rappels.
// 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 }); }Examinons le code spécifique d'enregistrement des événements et comment lier les événements natifs DOM sur le document.
// 事件注册 // 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 Regardons le code spécifique pour lier les événements à la phase de bouillonnement : <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); } } }Dans la méthode d'écoute, nous avons finalement découvert la méthode native d'enregistrement d'événements addEventListener. Seul le nœud de document appellera cette méthode, donc seul le nœud de document a des événements DOM. Cela simplifie grandement la logique des événements DOM et économise de la mémoire. 7-2. Stockage de l'événement
Une fois l'événement enregistré, la fonction de rappel liée à l'événement doit être stockée. De cette façon, ce n'est qu'après le déclenchement de l'événement que nous pouvons trouver le rappel correspondant à déclencher. Dans le code initial, nous avons vu que la méthode putListener est utilisée pour stocker les rappels d'événements.
// 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. Exécution de l'événement
1.合成事件本来就绑定在document上,完全可以获取这个document 2.stopImmediatePropagation可以阻止触发的document DOM上的事件,这十分有必要 3.不会阻止DOM 上的事件冒泡到document DOM. Recommandations associées :
Trois méthodes de transmission de valeurs couramment utilisées dans Vue
Implémentation de l'enregistrement des événements React Event
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!