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)
def _render(self) -> Tag:
def _render(self, props: dict[str, Any] | None = None) -> Tag:
"""Define how to render the component in React.
Args:
props: The props to render (if None, then use get_props).
Returns:
The tag to render.
"""
@ -370,16 +373,26 @@ class Component(Base, ABC):
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)
@ -501,14 +514,7 @@ class Component(Base, ABC):
"""
tag = self._render()
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],
contents=str(tag.contents),
props=tag.format_props(),
@ -949,10 +955,7 @@ class CustomComponent(Component):
Returns:
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]:
"""Get the prop vars.

View File

@ -11,7 +11,7 @@ from reflex.components.tags import Tag
from reflex.constants import EventTriggers
from reflex.event import EventChain
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.vars import BaseVar, Var, get_unique_variable_name
@ -82,23 +82,25 @@ class Form(ChakraComponent):
)
def _render(self) -> Tag:
return (
render_tag = (
super()
._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]:
# 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