Frontmatter
| id | 7011 |
| title | DOM Event Handling for Beginner Mode Functional Components |
| state | Closed |
| labels | enhancement |
| assignees | [] |
| createdAt | Jul 11, 2025, 3:59 AM |
| updatedAt | Jul 14, 2025, 1:27 AM |
| githubUrl | https://github.com/neomjs/neo/issues/7011 |
| author | tobiu |
| commentsCount | 1 |
| parentIssue | 6992 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Jul 14, 2025, 1:27 AM |
DOM Event Handling for Beginner Mode Functional Components
tobiu added parent issue #6992 on Jul 11, 2025, 3:59 AM

tobiu
Jul 13, 2025, 10:21 PM
Roadmap for useEvent Hook in Functional Components
This document outlines the conceptual design and implementation plan for the useEvent hook, enabling idiomatic DOM event handling within "Beginner Mode" functional components in Neo.mjs.
1. Core Concept
The useEvent hook will allow functional components to declare their intent to listen for DOM events. The actual registration and de-registration of these listeners with Neo.manager.DomEvent will be managed by the component's lifecycle, ensuring createVdom remains a pure function focused solely on VDOM generation.
2. Key Components & Their Roles
2.1. useEvent Hook (within createVdom of functional components)
- Purpose: To collect event listener specifications (event type, handler function, optional delegate selector).
- Mechanism:
- It will obtain a reference to the current functional component instance (via a context mechanism, e.g.,
_currentComponentInstance). - It will add the event listener specification (e.g.,
{ eventType: 'click', handler: myHandler, delegate: '.my-class' }) to a non-reactive internal array or map on the component instance (e.g.,this._pendingDomEvents). This data collection operation itself must not trigger any reactive updates of thecreateVdomeffect. - The handler function provided to
useEventwill be a closure that captures the current state of the functional component (e.g.,countfromuseConfig).
- It will obtain a reference to the current functional component instance (via a context mechanism, e.g.,
2.2. Neo.functional.component.Base (The Functional Component Instance)
- New Internal Property:
_pendingDomEvents(e.g., an array) to temporarily store event listener specifications collected during acreateVdomrun. - Lifecycle Integration:
afterSetMountedHook: This is the critical point for actual event listener registration.- It will iterate through
this._pendingDomEvents. - For each specification, it will call
this.addDomListeners()(a method provided by theDomEventsmixin). This is where the actual interaction withNeo.manager.DomEventoccurs, sending instructions to the main thread to register the listeners. - After processing all pending events,
this._pendingDomEventsshould be cleared to prevent re-registration on subsequentcreateVdomruns.
- It will iterate through
destroyHook:- It will call
this.removeDomListeners()(from theDomEventsmixin) to ensure all registered listeners are properly cleaned up when the component instance is destroyed, preventing memory leaks.
- It will call
2.3. Neo.mixin.DomEvents
- Role: Continues to provide the
domListeners_config and theaddDomListeners/removeDomListenersmethods. These methods serve as the interface for components to interact withNeo.manager.DomEventfor event registration and de-registration.
2.4. Neo.manager.DomEvent (App Worker)
- Role: Remains the central hub for delegated DOM event management within the app worker. It receives event registration/de-registration requests from components (via
addDomListeners/removeDomListeners) and handles the communication with the main thread for actual DOM event observation and dispatch.
3. Benefits of this Approach
- Purity of
createVdom: ThecreateVdomfunction remains a pure function, focused solely on generating the VDOM structure. Side effects like DOM event registration are deferred to appropriate lifecycle hooks. - Correct Lifecycle Management: Event listeners are correctly added only when the component's DOM is mounted and removed when the component is destroyed, preventing memory leaks and ensuring robust behavior.
- Leveraging Existing Infrastructure: Fully utilizes the powerful, optimized, and already established
Neo.manager.DomEventandDomEventsmixin. - Idiomatic Functional Component API: Provides a clean, declarative, and intuitive
useEventhook that aligns with the functional component paradigm. - Reactive System Compatibility: Ensures that the event registration process does not interfere with or create unintended dependencies within the
core.Effectthat wrapscreateVdom.
4. Next Steps (Implementation)
- Implement
useEventHook: Write theuseEventfunction. This hook will retrieve the current functional component instance by accessingEffectManager.getActiveEffect().componentIdand then usingNeo.getComponent()to get the instance. It will then collect event specifications and store them on the component instance's_pendingDomEventsproperty. - Integrate with
FunctionalBase: ModifyNeo.functional.component.Baseto manage the_pendingDomEventsproperty and integrate theaddDomListeners/removeDomListenerscalls within its lifecycle (afterSetMountedanddestroy). - Testing and Documentation: Thoroughly test the new hook and provide clear documentation and examples.
tobiu closed this issue on Jul 14, 2025, 1:27 AM
1. Summary
Explore and define the idiomatic way for developers to handle DOM events within "Beginner Mode" functional components, ensuring integration with Neo.mjs's powerful, separate DOM event engine.
2. Rationale
Unlike some other frameworks, Neo.mjs has a dedicated and highly optimized DOM event management system that operates separately from the VDOM. Directly embedding
listenerswithin the VDOM (as is common in React) is not the Neo.mjs way and can lead to confusion and suboptimal performance. This ticket aims to define a clear, intuitive, and performant pattern for event handling in the simplified functional component mode.3. Scope & Implementation Plan
Neo.manager.DomEvent) is currently used and how it can be exposed in a functional, hook-like manner.useEventhook or similar API that allows developers to attach event listeners to VDOM nodes declaratively within theircreateVdomfunction, without directly embeddinglistenersin the VDOM object.Neo.functional.component.Baseinstance and theNeo.manager.DomEvent.4. Example Usage (Conceptual)
import { defineComponent } from 'neo/functional/defineComponent.mjs'; import { useConfig } from 'neo/functional/useConfig.mjs'; import { useEvent } from 'neo/functional/useEvent.mjs'; // New hook export default defineComponent(function MyClickableDiv(config) { const [count, setCount] = useConfig(0); // Attach a click listener using the new hook useEvent('click', (event) => { setCount(count + 1); console.log('Div clicked!', event); }); return { tag: 'div', html: `Clicked ${count} times`, // No listeners property directly in VDOM }; });5. Definition of Done
useEvent) are designed.