MCPcopy
hub / github.com/reflex-dev/reflex / MemoizeStatefulPlugin

Class MemoizeStatefulPlugin

reflex/compiler/plugins/memoize.py:203–402  ·  view source on GitHub ↗

Auto-memoize stateful components with experimental-memo wrappers. Registered in ``default_page_plugins`` before ``DefaultCollectorPlugin``. Components either render as passthrough memo wrappers or snapshot memo wrappers (see ``get_memoization_strategy``): - Snapshot wrappers (``Mem

Source from the content-addressed store, hash-verified

201
202@dataclasses.dataclass(frozen=True, slots=True)
203class MemoizeStatefulPlugin(Plugin):
204 """Auto-memoize stateful components with experimental-memo wrappers.
205
206 Registered in ``default_page_plugins`` before ``DefaultCollectorPlugin``.
207 Components either render as passthrough memo wrappers or snapshot memo
208 wrappers (see ``get_memoization_strategy``):
209
210 - Snapshot wrappers (``MemoizationLeaf``-style boundaries and structural
211 ``Foreach`` wrappers): wrapped in ``enter_component``
212 and returned with empty structural children. The walker skips descent, so
213 hooks attached to the captured body are compiled into the memo body only.
214 - Passthrough wrappers are wrapped in
215 ``leave_component`` after descendants have already compiled, so any inner
216 memo wrappers flow into this wrapper's children.
217
218 Descendants of a snapshot boundary are never independently memoized; the
219 boundary owns the wrapping decision for its whole subtree. This is tracked
220 via ``PageContext.memoize_suppressor_stack`` — a stack of component ids
221 that pushed suppression, popped in ``leave_component`` when the matching
222 component leaves.
223 """
224
225 def enter_component(
226 self,
227 comp: BaseComponent,
228 /,
229 *,
230 page_context: PageContext,
231 compile_context: Any,
232 in_prop_tree: bool = False,
233 ) -> BaseComponent | ComponentAndChildren | None:
234 """Memoize snapshot-boundary subtrees before descent.
235
236 Snapshot boundaries (``MemoizationLeaf``-style, see
237 ``is_snapshot_boundary``) stash state-referencing hooks inside
238 internally-built structural children. If we waited until
239 ``leave_component`` to swap the boundary for its memo wrapper, the
240 walker would have already descended and the collector plugin would
241 have pulled those hooks into page scope. Returning the wrapper with
242 empty structural children here causes the walker to skip the descent
243 entirely — the boundary's full snapshot lives only in the memo
244 component definition compiled separately.
245
246 Non-boundary components are handled in ``leave_component`` so their
247 already-compiled children flow into the wrapper.
248
249 Args:
250 comp: The component being visited.
251 page_context: The active page context.
252 compile_context: The active compile context.
253 in_prop_tree: Whether the component is in a prop subtree.
254
255 Returns:
256 A ``(wrapper, ())`` replacement for memoized boundaries, otherwise
257 ``None``.
258 """
259 if in_prop_tree:
260 return None

Callers 3

_compile_page_contextFunction · 0.90
default_page_pluginsFunction · 0.90

Calls

no outgoing calls

Tested by 1

_compile_page_contextFunction · 0.72