diff --git a/reflex/components/component.py b/reflex/components/component.py index c1b33b1f7..e1c365e6d 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -255,6 +255,7 @@ class Component(BaseComponent, ABC): Raises: TypeError: If an invalid prop is passed. + ValueError: If an event trigger passed is not valid. """ # Set the id and children initially. children = kwargs.get("children", []) @@ -284,6 +285,12 @@ class Component(BaseComponent, ABC): # Iterate through the kwargs and set the props. for key, value in kwargs.items(): + if key.startswith("on_") and key not in triggers and key not in props: + raise ValueError( + f"The {(comp_name := type(self).__name__)} does not take in an `{key}` event trigger. If {comp_name}" + f" is a third party component make sure to add `{key}` to the component's event triggers. " + f"visit https://reflex.dev/docs/wrapping-react/logic/#event-triggers for more info." + ) if key in triggers: # Event triggers are bound to event chains. field_type = EventChain diff --git a/tests/components/test_component.py b/tests/components/test_component.py index 25756b552..21ec409af 100644 --- a/tests/components/test_component.py +++ b/tests/components/test_component.py @@ -1569,3 +1569,28 @@ def test_custom_component_declare_event_handlers_in_fields(): parse_args_spec(custom_triggers[trigger_name]), ): assert v1.equals(v2) + + +def test_invalid_event_trigger(): + class TriggerComponent(Component): + on_push: Var[bool] + + def get_event_triggers(self) -> Dict[str, Any]: + """Test controlled triggers. + + Returns: + Test controlled triggers. + """ + return { + **super().get_event_triggers(), + "on_a": lambda: [], + } + + trigger_comp = TriggerComponent.create + + # test that these do not throw errors. + trigger_comp(on_push=True) + trigger_comp(on_a=rx.console_log("log")) + + with pytest.raises(ValueError): + trigger_comp(on_b=rx.console_log("log"))