ENG-10089: Support custom JS wrappers and bare functions in @rx.memo#6730
ENG-10089: Support custom JS wrappers and bare functions in @rx.memo#6730masenf wants to merge 3 commits into
Conversation
@rx.memo now accepts a wrapper= keyword controlling the JS function the compiled function component is wrapped in. The default is unchanged: React's memo, now expressed as DEFAULT_MEMO_WRAPPER — a FunctionStringVar carrying its own react import. Passing another Var swaps the wrapper (its VarData imports ride along, feeding module imports and frontend package detection), and wrapper=None exports the bare function component. - MemoComponentDefinition grows a wrapper field; the compiler emits it via the render dict and a shared _render_memo_component template helper. - The react memo import moves off _MEMO_BASE_IMPORTS onto the wrapper var, so modules whose memos swap or drop the wrapper no longer import it. - Var-returning memos reject an explicit wrapper= with a TypeError. - @rx.memo() with no arguments now also works, typed via a _MemoDecorator protocol so both component- and var-returning memos check cleanly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CtJ4TyjTc7nDyDyFn446TH
Greptile SummaryThis PR adds configurable JavaScript wrappers for
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (3): Last reviewed commit: "Add changelog news fragments for memo wr..." | Re-trigger Greptile |
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0bb48818b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
An inline wrapper expression like `(Comp) => observer(Comp)` concatenated directly against the component function would swallow the call into the arrow body instead of invoking the wrapper. Wrap anything that isn't an identifier/member chain in parens; `memo(...)` output is unchanged. Addresses PR #6730 review feedback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CtJ4TyjTc7nDyDyFn446TH
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CtJ4TyjTc7nDyDyFn446TH
Type of change
Description
Extends
@rx.memoto support customizing the JavaScript wrapper applied to compiled component memos, or omitting the wrapper entirely to export bare function components.Changes
Core feature:
DEFAULT_MEMO_WRAPPERconstant: React'smemofunction with its own import@rx.memodecorator to accept optionalwrapper=keyword argument:@rx.memoor@rx.memo(): Uses React'smemo(default behavior, unchanged)@rx.memo(wrapper=custom_var): Wraps the function component in a custom JS helper (e.g., MobXobserver)@rx.memo(wrapper=None): Exports the bare function component with no wrapperVaritself, so custom wrappers bring their own imports andwrapper=Nonepulls in nothingwrapper=only applies to component-returning memos; var-returning memos reject the argument with a clear errorCompiler updates:
memo_components_templateandmemo_single_component_templateto render the wrapper conditionally_MEMO_BASE_IMPORTSto remove the hardcodedmemoimport (now supplied byDEFAULT_MEMO_WRAPPER)compile_experimental_component_memoto extract and merge wrapper var data into the imports collectionDocumentation:
wrapperparameterTests
test_default_memo_wrapper_is_react_memo,test_component_memo_default_wrapper)test_component_memo_wrapper_none_emits_bare_function,test_component_memo_wrapper_none_in_unmirrored_module)test_component_memo_custom_wrapper)test_var_returning_memo_rejects_wrapper)test_memo_decorator_parens_form_matches_bare_decorator)test_memo_wrapper_none_renders_and_updates) verifying bare function components render and update correctlyBackward compatibility
Fully backward compatible. Existing
@rx.memodecorators continue to work unchanged, using React'smemoby default.https://claude.ai/code/session_01CtJ4TyjTc7nDyDyFn446TH