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

This commit is contained in:
Masen Furer 2023-11-13 23:27:42 -08:00 committed by GitHub
parent 812ca2377b
commit f3929f47e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 37 deletions

View File

@ -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. if props is None:
props = { # Add component props to the tag.
attr[:-1] if attr.endswith("_") else attr: getattr(self, attr) props = {
for attr in self.get_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. # Add ref to element if `id` is not None.
ref = self.get_ref() ref = self.get_ref()
if ref is not None: if ref is not None:
props["ref"] = Var.create(ref, _var_is_local=False) 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( tag.set(
**self.event_triggers,
key=self.key,
id=self.id,
class_name=self.class_name,
**self._get_style(),
**self.custom_attrs,
).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( return super()._render(props=self.props)
name=self.tag if not self.alias else self.alias,
special_props=self.special_props,
).add_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.

View File

@ -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),
)
) )
if EventTriggers.ON_SUBMIT in self.event_triggers:
def render(self) -> dict: render_tag.add_props(
"""Render the component. **{
EventTriggers.ON_SUBMIT: BaseVar(
Returns: _var_name=f"handleSubmit{self.handle_submit_unique_name}",
The rendered component. _var_type=EventChain,
""" )
self.event_triggers[EventTriggers.ON_SUBMIT] = BaseVar( }
_var_name=f"handleSubmit{self.handle_submit_unique_name}", )
_var_type=EventChain, return render_tag
)
return super().render()
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.

View File

@ -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