Generalize MemoizationLeaf Component mixin (#2247)
This commit is contained in:
parent
1109f8f508
commit
49ccd2f1fb
@ -1,6 +1,6 @@
|
||||
"""The head component."""
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.component import Component, MemoizationLeaf
|
||||
|
||||
|
||||
class NextHeadLib(Component):
|
||||
@ -9,7 +9,7 @@ class NextHeadLib(Component):
|
||||
library = "next/head"
|
||||
|
||||
|
||||
class Head(NextHeadLib):
|
||||
class Head(NextHeadLib, MemoizationLeaf):
|
||||
"""Head Component."""
|
||||
|
||||
tag = "NextHead"
|
||||
|
@ -7,7 +7,7 @@ from typing import Any, Dict, Literal, Optional, Union, overload
|
||||
from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.component import Component, MemoizationLeaf
|
||||
|
||||
class NextHeadLib(Component):
|
||||
@overload
|
||||
@ -88,7 +88,7 @@ class NextHeadLib(Component):
|
||||
"""
|
||||
...
|
||||
|
||||
class Head(NextHeadLib):
|
||||
class Head(NextHeadLib, MemoizationLeaf):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
@ -147,7 +147,7 @@ class Head(NextHeadLib):
|
||||
] = None,
|
||||
**props
|
||||
) -> "Head":
|
||||
"""Create the component.
|
||||
"""Create a new memoization leaf component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
@ -160,9 +160,6 @@ class Head(NextHeadLib):
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
The component.
|
||||
|
||||
Raises:
|
||||
TypeError: If an invalid child is passed.
|
||||
The memoization leaf
|
||||
"""
|
||||
...
|
||||
|
@ -1674,3 +1674,35 @@ class StatefulComponent(BaseComponent):
|
||||
if stateful_component is not None:
|
||||
return stateful_component
|
||||
return component
|
||||
|
||||
|
||||
class MemoizationLeaf(Component):
|
||||
"""A component that does not separately memoize its children.
|
||||
|
||||
Any component which depends on finding the exact names of children
|
||||
components within it, should be a memoization leaf so the compiler
|
||||
does not replace the provided child tags with memoized tags.
|
||||
|
||||
During creation, a memoization leaf will mark itself as wanting to be
|
||||
memoized if any of its children return any hooks.
|
||||
"""
|
||||
|
||||
_memoization_mode = MemoizationMode(recursive=False)
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props) -> Component:
|
||||
"""Create a new memoization leaf component.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
The memoization leaf
|
||||
"""
|
||||
comp = super().create(*children, **props)
|
||||
if comp.get_hooks():
|
||||
comp._memoization_mode = cls._memoization_mode.copy(
|
||||
update={"disposition": MemoizationDisposition.ALWAYS}
|
||||
)
|
||||
return comp
|
||||
|
@ -770,10 +770,10 @@ class FunnelChart(RechartsCharts):
|
||||
] = None,
|
||||
**props
|
||||
) -> "FunnelChart":
|
||||
"""Create a Recharts chart container component (mixin).
|
||||
"""Create a new memoization leaf component.
|
||||
|
||||
Args:
|
||||
*children: The children components.
|
||||
*children: The children of the component.
|
||||
data: The source data, in which each element is an object.
|
||||
sync_id: If any two categorical charts(rx.line_chart, rx.area_chart, rx.bar_chart, rx.composed_chart) have the same sync_id, these two charts can sync the position GraphingTooltip, and the start_index, end_index of Brush.
|
||||
sync_method: When sync_id is provided, allows customisation of how the charts will synchronize GraphingTooltips and brushes. Using 'index' (default setting), other charts will reuse current datum's index within the data array. In cases where data does not have the same length, this might yield unexpected results. In that case use 'value' which will try to match other charts values, or a fully custom function which will receive tick, data as argument and should return an index. 'index' | 'value' | function
|
||||
@ -791,7 +791,7 @@ class FunnelChart(RechartsCharts):
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
A Recharts component.
|
||||
The memoization leaf
|
||||
"""
|
||||
...
|
||||
|
||||
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List, Union
|
||||
|
||||
from reflex.components.component import MemoizationLeaf
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.vars import Var
|
||||
|
||||
@ -13,11 +14,10 @@ from .recharts import (
|
||||
LiteralPosition,
|
||||
LiteralVerticalAlign,
|
||||
Recharts,
|
||||
RechartsMemoizationLeafMixin,
|
||||
)
|
||||
|
||||
|
||||
class ResponsiveContainer(Recharts, RechartsMemoizationLeafMixin):
|
||||
class ResponsiveContainer(Recharts, MemoizationLeaf):
|
||||
"""A base class for responsive containers in Recharts."""
|
||||
|
||||
tag = "ResponsiveContainer"
|
||||
|
@ -8,6 +8,7 @@ from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
from typing import Any, Dict, List, Union
|
||||
from reflex.components.component import MemoizationLeaf
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.vars import Var
|
||||
from .recharts import (
|
||||
@ -17,10 +18,9 @@ from .recharts import (
|
||||
LiteralPosition,
|
||||
LiteralVerticalAlign,
|
||||
Recharts,
|
||||
RechartsMemoizationLeafMixin,
|
||||
)
|
||||
|
||||
class ResponsiveContainer(Recharts, RechartsMemoizationLeafMixin):
|
||||
class ResponsiveContainer(Recharts, MemoizationLeaf):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
@ -85,10 +85,10 @@ class ResponsiveContainer(Recharts, RechartsMemoizationLeafMixin):
|
||||
] = None,
|
||||
**props
|
||||
) -> "ResponsiveContainer":
|
||||
"""Create a Recharts chart container component (mixin).
|
||||
"""Create a new memoization leaf component.
|
||||
|
||||
Args:
|
||||
*children: The children components.
|
||||
*children: The children of the component.
|
||||
aspect: The aspect ratio of the container. The final aspect ratio of the SVG element will be (width / height) * aspect. Number
|
||||
width: The width of chart container. Can be a number or string
|
||||
height: The height of chart container. Number
|
||||
@ -104,7 +104,7 @@ class ResponsiveContainer(Recharts, RechartsMemoizationLeafMixin):
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
A Recharts component.
|
||||
The memoization leaf
|
||||
"""
|
||||
...
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
"""A component that wraps a recharts lib."""
|
||||
from typing import Literal
|
||||
|
||||
from reflex.components.component import Component, NoSSRComponent
|
||||
from reflex.constants import MemoizationDisposition, MemoizationMode
|
||||
from reflex.components.component import Component, MemoizationLeaf, NoSSRComponent
|
||||
|
||||
|
||||
class Recharts(Component):
|
||||
@ -11,35 +10,7 @@ class Recharts(Component):
|
||||
library = "recharts@2.8.0"
|
||||
|
||||
|
||||
class RechartsMemoizationLeafMixin(Component):
|
||||
"""A mixin for Recharts components that must not memoize their children separately.
|
||||
|
||||
This includes all chart types and ResponsiveContainer itself.
|
||||
"""
|
||||
|
||||
_memoization_mode = MemoizationMode(recursive=False)
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props) -> Component:
|
||||
"""Create a Recharts chart container component (mixin).
|
||||
|
||||
Args:
|
||||
*children: The children components.
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
A Recharts component.
|
||||
"""
|
||||
comp = super().create(*children, **props)
|
||||
if comp.get_hooks():
|
||||
# If any of the children depend on state, then this instance needs to memoize.
|
||||
comp._memoization_mode = cls._memoization_mode.copy(
|
||||
update={"disposition": MemoizationDisposition.ALWAYS},
|
||||
)
|
||||
return comp
|
||||
|
||||
|
||||
class RechartsCharts(NoSSRComponent, RechartsMemoizationLeafMixin):
|
||||
class RechartsCharts(NoSSRComponent, MemoizationLeaf):
|
||||
"""A component that wraps a recharts lib."""
|
||||
|
||||
library = "recharts@2.8.0"
|
||||
|
@ -8,8 +8,7 @@ from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
from typing import Literal
|
||||
from reflex.components.component import Component, NoSSRComponent
|
||||
from reflex.constants import MemoizationDisposition, MemoizationMode
|
||||
from reflex.components.component import Component, MemoizationLeaf, NoSSRComponent
|
||||
|
||||
class Recharts(Component):
|
||||
@overload
|
||||
@ -90,83 +89,7 @@ class Recharts(Component):
|
||||
"""
|
||||
...
|
||||
|
||||
class RechartsMemoizationLeafMixin(Component):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
cls,
|
||||
*children,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_focus: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mount: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_scroll: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
**props
|
||||
) -> "RechartsMemoizationLeafMixin":
|
||||
"""Create a Recharts chart container component (mixin).
|
||||
|
||||
Args:
|
||||
*children: The children components.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
class_name: The class name for the component.
|
||||
autofocus: Whether the component should take the focus once the page is loaded
|
||||
custom_attrs: custom attribute
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
A Recharts component.
|
||||
"""
|
||||
...
|
||||
|
||||
class RechartsCharts(NoSSRComponent, RechartsMemoizationLeafMixin):
|
||||
class RechartsCharts(NoSSRComponent, MemoizationLeaf):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
@ -225,10 +148,10 @@ class RechartsCharts(NoSSRComponent, RechartsMemoizationLeafMixin):
|
||||
] = None,
|
||||
**props
|
||||
) -> "RechartsCharts":
|
||||
"""Create a Recharts chart container component (mixin).
|
||||
"""Create a new memoization leaf component.
|
||||
|
||||
Args:
|
||||
*children: The children components.
|
||||
*children: The children of the component.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -238,7 +161,7 @@ class RechartsCharts(NoSSRComponent, RechartsMemoizationLeafMixin):
|
||||
**props: The props of the component.
|
||||
|
||||
Returns:
|
||||
A Recharts component.
|
||||
The memoization leaf
|
||||
"""
|
||||
...
|
||||
|
||||
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, Optional, overload
|
||||
|
||||
from reflex.components.component import BaseComponent, Component
|
||||
from reflex.components.component import BaseComponent, Component, MemoizationLeaf
|
||||
from reflex.components.layout.fragment import Fragment
|
||||
from reflex.components.tags import CondTag, Tag
|
||||
from reflex.constants import Dirs
|
||||
@ -15,7 +15,7 @@ _IS_TRUE_IMPORT = {
|
||||
}
|
||||
|
||||
|
||||
class Cond(Component):
|
||||
class Cond(MemoizationLeaf):
|
||||
"""Render one of two components based on a condition."""
|
||||
|
||||
# The cond to determine which component to render.
|
||||
|
Loading…
Reference in New Issue
Block a user