diff --git a/reflex/.templates/web/utils/state.js b/reflex/.templates/web/utils/state.js index 35a129337..59c25cd16 100644 --- a/reflex/.templates/web/utils/state.js +++ b/reflex/.templates/web/utils/state.js @@ -213,6 +213,10 @@ export const applyEvent = async (event, socket) => { return false; } + // Only proceed if the socket is up, otherwise we throw the event into the void + if (!socket) { + return false; + } // Update token and router data (if missing). event.token = getToken(); if ( @@ -246,6 +250,10 @@ export const applyEvent = async (event, socket) => { * @returns Whether the event was sent. */ export const applyRestEvent = async (event, socket) => { + // Only proceed if the socket is up, otherwise we throw the event into the void + if (!socket) { + return false; + } let eventSent = false; if (event.handler === "uploadFiles") { @@ -282,11 +290,6 @@ export const queueEvents = async (events, socket) => { * @param socket The socket object to send the event on. */ export const processEvent = async (socket) => { - // Only proceed if the socket is up, otherwise we throw the event into the void - if (!socket) { - return; - } - // Only proceed if we're not already processing an event. if (event_queue.length === 0 || event_processing) { return; diff --git a/reflex/app.py b/reflex/app.py index 3704a3191..5441ce987 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -541,9 +541,7 @@ class App(LifespanMixin, Base): # Ensure state is enabled if this page uses state. if self.state is None: - if on_load or component._has_event_triggers( - exclude_event_trigger_values=[constants.ColorMode.TOGGLE] - ): + if on_load or component._has_stateful_event_triggers(): self._enable_state() else: for var in component._get_vars(include_children=True): diff --git a/reflex/components/component.py b/reflex/components/component.py index c0b721ba9..2c60f09d4 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -7,7 +7,7 @@ import typing from abc import ABC, abstractmethod from functools import lru_cache, wraps from hashlib import md5 -from types import SimpleNamespace +from types import SimpleNamespace, LambdaType from typing import ( Any, Callable, @@ -1113,65 +1113,38 @@ class Component(BaseComponent, ABC): return vars - def _event_triggers_contains_excluded_values( - self, exclude_event_trigger_values: list[str] - ) -> bool: - """Check if the component's event triggers contain excluded value names. - When an event trigger value is a Var, we check the var name else, if the value is - an EventChain, we go through all the events comparing the function names (or qualname for non-state - event handlers). - Args: - exclude_event_trigger_values: excluded values to check for. - - Returns: - If the component's event triggers contain any excluded value - - """ + def _event_trigger_values_use_state(self) -> bool: for trigger in self.event_triggers.values(): if isinstance(trigger, EventChain): for event in trigger.events: - if ( - ( - event.handler.state_full_name - and event.handler.fn.__name__ - in exclude_event_trigger_values - ) - or not event.handler.state_full_name - and event.handler.fn.__qualname__ - in exclude_event_trigger_values - ): + if event.handler.state_full_name or isinstance(event.handler.fn, LambdaType) and event.handler.fn.__name__== (lambda: None).__name__: return True - elif ( - isinstance(trigger, Var) - and trigger._var_name in exclude_event_trigger_values - ): + elif isinstance(trigger, Var) and trigger._var_state: return True return False - def _has_event_triggers( - self, exclude_event_trigger_values: list[str] | None = None - ) -> bool: - """Check if the component or children have any event triggers. + def _has_stateful_event_triggers(self): - Args: - exclude_event_trigger_values: Event trigger var names to exclude from this check. + if self.event_triggers and self._event_trigger_values_use_state(): + return True + else: + for child in self.children: + if isinstance(child, Component) and child._has_stateful_event_triggers(): + return True + return False + + def _has_event_triggers(self) -> bool: + """Check if the component or children have any event triggers. Returns: True if the component or children have any event triggers. """ - if exclude_event_trigger_values is None: - exclude_event_trigger_values = [] - - if self.event_triggers and not self._event_triggers_contains_excluded_values( - exclude_event_trigger_values - ): + if self.event_triggers: return True else: for child in self.children: - if isinstance(child, Component) and child._has_event_triggers( - exclude_event_trigger_values - ): + if isinstance(child, Component) and child._has_event_triggers(): return True return False diff --git a/tests/components/test_component.py b/tests/components/test_component.py index d98085373..9680af762 100644 --- a/tests/components/test_component.py +++ b/tests/components/test_component.py @@ -2146,6 +2146,17 @@ class TriggerState(rx.State): ["_console", "_alert"], False, ), +( + rx.box( + rx.text( + "random text", + on_click=lambda x: x, + ), + ), + ["_console", "_alert"], + False, + ), + ], ) def test_has_event_triggers(component, exclude_event_trigger_values, output):