[reflex-web tweaks] Do not memoize children of InputGroup (#2230)
This commit is contained in:
parent
a86bcb3c72
commit
a2d5bbc133
@ -71,6 +71,8 @@ def FormSubmitName():
|
||||
|
||||
class FormState(rx.State):
|
||||
form_data: dict = {}
|
||||
val: str = "foo"
|
||||
options: list[str] = ["option1", "option2"]
|
||||
|
||||
def form_submit(self, form_data: dict):
|
||||
self.form_data = form_data
|
||||
@ -96,15 +98,24 @@ def FormSubmitName():
|
||||
rx.switch(name="bool_input4"),
|
||||
rx.slider(name="slider_input"),
|
||||
rx.range_slider(name="range_input"),
|
||||
rx.radio_group(["option1", "option2"], name="radio_input"),
|
||||
rx.select(["option1", "option2"], name="select_input"),
|
||||
rx.radio_group(FormState.options, name="radio_input"),
|
||||
rx.select(FormState.options, name="select_input"),
|
||||
rx.text_area(name="text_area_input"),
|
||||
rx.input(
|
||||
name="debounce_input",
|
||||
debounce_timeout=0,
|
||||
on_change=rx.console_log,
|
||||
rx.input_group(
|
||||
rx.input_left_element(rx.icon(tag="chevron_right")),
|
||||
rx.input(
|
||||
name="debounce_input",
|
||||
debounce_timeout=0,
|
||||
on_change=rx.console_log,
|
||||
),
|
||||
rx.input_right_element(rx.icon(tag="chevron_left")),
|
||||
),
|
||||
rx.button_group(
|
||||
rx.button("Submit", type_="submit"),
|
||||
rx.icon_button(FormState.val, icon=rx.icon(tag="add")),
|
||||
variant="outline",
|
||||
is_attached=True,
|
||||
),
|
||||
rx.button("Submit", type_="submit"),
|
||||
),
|
||||
on_submit=FormState.form_submit,
|
||||
custom_attrs={"action": "/invalid"},
|
||||
|
@ -23,7 +23,14 @@ from typing import (
|
||||
from reflex.base import Base
|
||||
from reflex.compiler.templates import STATEFUL_COMPONENT
|
||||
from reflex.components.tags import Tag
|
||||
from reflex.constants import Dirs, EventTriggers, Hooks, Imports, PageNames
|
||||
from reflex.constants import (
|
||||
Dirs,
|
||||
EventTriggers,
|
||||
Hooks,
|
||||
Imports,
|
||||
MemoizationMode,
|
||||
PageNames,
|
||||
)
|
||||
from reflex.event import (
|
||||
EventChain,
|
||||
EventHandler,
|
||||
@ -150,6 +157,9 @@ class Component(BaseComponent, ABC):
|
||||
# custom attribute
|
||||
custom_attrs: Dict[str, Union[Var, str]] = {}
|
||||
|
||||
# When to memoize this component and its children.
|
||||
_memoization_mode: MemoizationMode = MemoizationMode()
|
||||
|
||||
@classmethod
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
"""Set default properties.
|
||||
@ -1643,14 +1653,13 @@ class StatefulComponent(BaseComponent):
|
||||
Returns:
|
||||
The memoized component tree.
|
||||
"""
|
||||
from reflex.components.layout.foreach import Foreach
|
||||
|
||||
# Foreach must be memoized as a single component to retain index Var context.
|
||||
if not isinstance(component, Foreach):
|
||||
component.children = [
|
||||
cls.compile_from(child) for child in component.children
|
||||
]
|
||||
if isinstance(component, Component):
|
||||
if component._memoization_mode.recursive:
|
||||
# Recursively memoize stateful children (default).
|
||||
component.children = [
|
||||
cls.compile_from(child) for child in component.children
|
||||
]
|
||||
# Memoize this component if it depends on state.
|
||||
stateful_component = cls.create(component)
|
||||
if stateful_component is not None:
|
||||
return stateful_component
|
||||
|
@ -9,7 +9,7 @@ from reflex.components.libs.chakra import (
|
||||
LiteralButtonSize,
|
||||
LiteralInputVariant,
|
||||
)
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.constants import EventTriggers, MemoizationMode
|
||||
from reflex.utils import imports
|
||||
from reflex.vars import Var
|
||||
|
||||
@ -107,6 +107,8 @@ class InputGroup(ChakraComponent):
|
||||
|
||||
tag = "InputGroup"
|
||||
|
||||
_memoization_mode = MemoizationMode(recursive=False)
|
||||
|
||||
|
||||
class InputLeftAddon(ChakraComponent):
|
||||
"""The InputLeftAddon component is a component that is used to add an addon to the left of an input."""
|
||||
|
@ -15,7 +15,7 @@ from reflex.components.libs.chakra import (
|
||||
LiteralButtonSize,
|
||||
LiteralInputVariant,
|
||||
)
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.constants import EventTriggers, MemoizationMode
|
||||
from reflex.utils import imports
|
||||
from reflex.vars import Var
|
||||
|
||||
|
@ -8,12 +8,15 @@ from typing import Any, Callable, Iterable
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.layout.fragment import Fragment
|
||||
from reflex.components.tags import IterTag
|
||||
from reflex.constants import MemoizationMode
|
||||
from reflex.vars import Var
|
||||
|
||||
|
||||
class Foreach(Component):
|
||||
"""A component that takes in an iterable and a render function and renders a list of components."""
|
||||
|
||||
_memoization_mode = MemoizationMode(recursive=False)
|
||||
|
||||
# The iterable to create components from.
|
||||
iterable: Var[Iterable]
|
||||
|
||||
|
@ -25,6 +25,8 @@ from .compiler import (
|
||||
Ext,
|
||||
Hooks,
|
||||
Imports,
|
||||
MemoizationDisposition,
|
||||
MemoizationMode,
|
||||
PageNames,
|
||||
)
|
||||
from .config import (
|
||||
@ -75,6 +77,8 @@ __ALL__ = [
|
||||
IS_WINDOWS,
|
||||
LOCAL_STORAGE,
|
||||
LogLevel,
|
||||
MemoizationDisposition,
|
||||
MemoizationMode,
|
||||
Next,
|
||||
Node,
|
||||
NOCOMPILE_FILE,
|
||||
|
@ -1,7 +1,9 @@
|
||||
"""Compiler variables."""
|
||||
import enum
|
||||
from enum import Enum
|
||||
from types import SimpleNamespace
|
||||
|
||||
from reflex.base import Base
|
||||
from reflex.constants import Dirs
|
||||
from reflex.utils.imports import ImportVar
|
||||
|
||||
@ -104,3 +106,21 @@ class Hooks(SimpleNamespace):
|
||||
"""Common sets of hook declarations."""
|
||||
|
||||
EVENTS = f"const [{CompileVars.ADD_EVENTS}, {CompileVars.CONNECT_ERROR}] = useContext(EventLoopContext);"
|
||||
|
||||
|
||||
class MemoizationDisposition(enum.Enum):
|
||||
"""The conditions under which a component should be memoized."""
|
||||
|
||||
# If the component uses state or events, it should be memoized.
|
||||
STATEFUL = "stateful"
|
||||
# TODO: add more modes, like always and never
|
||||
|
||||
|
||||
class MemoizationMode(Base):
|
||||
"""The mode for memoizing a Component."""
|
||||
|
||||
# The conditions under which the component should be memoized.
|
||||
disposition: MemoizationDisposition = MemoizationDisposition.STATEFUL
|
||||
|
||||
# Whether children of this component should be memoized first.
|
||||
recursive: bool = True
|
||||
|
@ -44,6 +44,7 @@ EXCLUDED_PROPS = [
|
||||
"is_default",
|
||||
"special_props",
|
||||
"_invalid_children",
|
||||
"_memoization_mode",
|
||||
"_valid_children",
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user