โ Troubleshooting & FAQ
Find answers to common issues and misconceptions when working with UIElement. From lifecycle callbacks to context usage, this section provides solutions and best practices to help you build robust and reactive Web Components.
Understanding UIElement's Philosophy
Prefer Light DOM Over Shadow DOM: What's the best way to handle event delegation, styling, and accessibility?
Use Light DOM as much as possible. It simplifies event handling, allows sharing global styles, and ensures better form handling, accessibility, and SEO. Use Shadow DOM only when necessary, for example, when including external content that needs strict style isolation or preventing style/script conflicts.
Server-Side Rendering & Client-Side Enhancement: How should I render HTML and manage client-side updates?
UIElement is designed to work with server-rendered HTML. Use any backend technology to produce the HTML, and rely on UIElement's client-side reactivity to update the DOM. To dynamically add elements, use techniques like cloning <template> tags and inserting them into the DOM.
Component Lifecycle & State Management
Lifecycle Callbacks: When should I use connectedCallback() vs. constructor()?
Always use connectedCallback() for initializing the component, as this is when it is connected to the DOM. Only use the constructor for simple initializations, since it runs before the element is attached to the DOM, so DOM and attributes are not yet available.
Signals vs. Direct DOM Manipulation: Should I manipulate the DOM directly or use signals?
Use signals to manage state changes. Signals automatically synchronize with the DOM through auto-effects, making your component reactive. Direct DOM manipulation bypasses this system and can lead to inconsistencies between state and the UI.
Attribute & Signal Pitfalls: How do I handle attributes and signals correctly?
Use states to parse attributes into appropriate types, such as numbers, booleans, or strings. This helps ensure that changes to the DOM and internal state are consistent. Remember that changes to signals are reactive, but attributes need to be mapped properly for reactivity.
Binding Events Correctly: How do I correctly bind event listeners in my component?
Bind all event listeners within connectedCallback() using methods like .on(event, callback). This ensures that the event listeners are bound after the component is attached to the DOM, providing reliable event handling.
Reactivity & Effects
Auto-Effects vs. Custom Effects: When should I use auto-effects and when custom effects?
Use auto-effects like setText() or toggleClass() for simple DOM updates based on signals. Use custom effects with effect() for more complex or multi-step operations. Avoid nesting auto-effects in custom effects to prevent double encapsulation.
Handling Asynchronous Operations: How do I handle async data fetching within effects?
Use effect(async () => { ... }) to handle async operations safely. Make sure that state changes within the effect do not cause infinite loops by adding appropriate conditions and guards.
Conditional State & Derived Signals: How do I manage derived signals and conditional state properly?
Initialize derived signals in connectedCallback() and use conditions to update their values based on changes to other signals. This ensures they are properly tracked in the reactivity system.
Debugging Complex State Interactions: How can I debug and manage complex state interactions?
Use console logs to track state changes and transitions. Break down complex effects into smaller auto-effects or simpler custom effects to improve readability and easier debugging.
Context & Inter-Component Communication
Using Context Correctly: How do I share state using context between components?
Use context providers and consumers to share state across components. Ensure that super.connectedCallback() and super.disconnectedCallback() are called in both context providers and consumers to correctly manage context requests and updates.
Passing & Sharing State: How do I pass state between components effectively?
Use the pass() function to transfer signals from parent to child components. This approach maintains loose coupling between components while enabling efficient state sharing and updates.
Styling & Accessibility
Style Scoping & Preventing Leaks: How do I avoid global style leaks and scope styles properly?
Scope styles within the custom element using CSS nesting or Shadow DOM where necessary. Avoid styling sub-component elements directly from parent components to ensure proper encapsulation and prevent global style leakage.
Accessibility Tips: How can I ensure my UI components are accessible?
Use ARIA attributes like aria-invalid and aria-errormessage to make forms accessible. Provide feedback through appropriate descriptions and error messages, making sure screen readers can announce the state of form elements and their validity.
Next Steps
We've covered the most common questions and issues when using UIElement. To explore the full capabilities of the library, head over to the API Reference for a complete overview of all methods, properties, signals, and lifecycle hooks.