Răsfoiți Sursa

form: only pass handleSubmit when on_submit is defined (#2162)

Masen Furer 1 an în urmă
părinte
comite
f3929f47e3

+ 25 - 22
reflex/components/component.py

@@ -358,9 +358,12 @@ class Component(Base, ABC):
 
 
         return _compile_component(self)
         return _compile_component(self)
 
 
-    def _render(self) -> Tag:
+    def _render(self, props: dict[str, Any] | None = None) -> Tag:
         """Define how to render the component in React.
         """Define how to render the component in React.
 
 
+        Args:
+            props: The props to render (if None, then use get_props).
+
         Returns:
         Returns:
             The tag to render.
             The tag to render.
         """
         """
@@ -370,16 +373,26 @@ class Component(Base, ABC):
             special_props=self.special_props,
             special_props=self.special_props,
         )
         )
 
 
-        # Add component props to the tag.
-        props = {
-            attr[:-1] if attr.endswith("_") else attr: getattr(self, attr)
-            for attr in self.get_props()
-        }
+        if props is None:
+            # Add component props to the tag.
+            props = {
+                attr[:-1] if attr.endswith("_") else attr: getattr(self, attr)
+                for attr in self.get_props()
+            }
 
 
-        # Add ref to element if `id` is not None.
-        ref = self.get_ref()
-        if ref is not None:
-            props["ref"] = Var.create(ref, _var_is_local=False)
+            # Add ref to element if `id` is not None.
+            ref = self.get_ref()
+            if ref is not None:
+                props["ref"] = Var.create(ref, _var_is_local=False)
+
+        props.update(
+            self.event_triggers,
+            key=self.key,
+            id=self.id,
+            class_name=self.class_name,
+        )
+        props.update(self._get_style())
+        props.update(self.custom_attrs)
 
 
         return tag.add_props(**props)
         return tag.add_props(**props)
 
 
@@ -501,14 +514,7 @@ class Component(Base, ABC):
         """
         """
         tag = self._render()
         tag = self._render()
         rendered_dict = dict(
         rendered_dict = dict(
-            tag.add_props(
-                **self.event_triggers,
-                key=self.key,
-                id=self.id,
-                class_name=self.class_name,
-                **self._get_style(),
-                **self.custom_attrs,
-            ).set(
+            tag.set(
                 children=[child.render() for child in self.children],
                 children=[child.render() for child in self.children],
                 contents=str(tag.contents),
                 contents=str(tag.contents),
                 props=tag.format_props(),
                 props=tag.format_props(),
@@ -949,10 +955,7 @@ class CustomComponent(Component):
         Returns:
         Returns:
             The tag to render.
             The tag to render.
         """
         """
-        return Tag(
-            name=self.tag if not self.alias else self.alias,
-            special_props=self.special_props,
-        ).add_props(**self.props)
+        return super()._render(props=self.props)
 
 
     def get_prop_vars(self) -> List[BaseVar]:
     def get_prop_vars(self) -> List[BaseVar]:
         """Get the prop vars.
         """Get the prop vars.

+ 17 - 15
reflex/components/forms/form.py

@@ -11,7 +11,7 @@ from reflex.components.tags import Tag
 from reflex.constants import EventTriggers
 from reflex.constants import EventTriggers
 from reflex.event import EventChain
 from reflex.event import EventChain
 from reflex.utils import imports
 from reflex.utils import imports
-from reflex.utils.format import format_event_chain
+from reflex.utils.format import format_event_chain, to_camel_case
 from reflex.utils.serializers import serialize
 from reflex.utils.serializers import serialize
 from reflex.vars import BaseVar, Var, get_unique_variable_name
 from reflex.vars import BaseVar, Var, get_unique_variable_name
 
 
@@ -82,23 +82,25 @@ class Form(ChakraComponent):
         )
         )
 
 
     def _render(self) -> Tag:
     def _render(self) -> Tag:
-        return (
+        render_tag = (
             super()
             super()
             ._render()
             ._render()
-            .remove_props("reset_on_submit", "handle_submit_unique_name")
+            .remove_props(
+                "reset_on_submit",
+                "handle_submit_unique_name",
+                to_camel_case(EventTriggers.ON_SUBMIT),
+            )
         )
         )
-
-    def render(self) -> dict:
-        """Render the component.
-
-        Returns:
-            The rendered component.
-        """
-        self.event_triggers[EventTriggers.ON_SUBMIT] = BaseVar(
-            _var_name=f"handleSubmit{self.handle_submit_unique_name}",
-            _var_type=EventChain,
-        )
-        return super().render()
+        if EventTriggers.ON_SUBMIT in self.event_triggers:
+            render_tag.add_props(
+                **{
+                    EventTriggers.ON_SUBMIT: BaseVar(
+                        _var_name=f"handleSubmit{self.handle_submit_unique_name}",
+                        _var_type=EventChain,
+                    )
+                }
+            )
+        return render_tag
 
 
     def _get_form_refs(self) -> Dict[str, Any]:
     def _get_form_refs(self) -> Dict[str, Any]:
         # Send all the input refs to the handler.
         # Send all the input refs to the handler.

+ 21 - 0
tests/components/forms/test_form.py

@@ -0,0 +1,21 @@
+from reflex.components.forms.form import Form
+from reflex.event import EventChain
+from reflex.vars import BaseVar
+
+
+def test_render_on_submit():
+    """Test that on_submit event chain is rendered as a separate function."""
+    submit_it = BaseVar(
+        _var_name="submit_it",
+        _var_type=EventChain,
+    )
+    f = Form.create(on_submit=submit_it)
+    exp_submit_name = f"handleSubmit{f.handle_submit_unique_name}"  # type: ignore
+    assert f"onSubmit={{{exp_submit_name}}}" in f.render()["props"]
+
+
+def test_render_no_on_submit():
+    """A form without on_submit should not render a submit handler."""
+    f = Form.create()
+    for prop in f.render()["props"]:
+        assert "onSubmit" not in prop