2828from reflex .utils .exceptions import ReflexError
2929from reflex .utils .exec import is_prod_mode
3030from reflex .utils .format import to_title_case
31- from reflex .utils .imports import ImportVar
31+ from reflex .utils .imports import ImportVar , ParsedImportDict
3232from reflex .utils .prerequisites import get_web_dir
3333from reflex .vars .base import LiteralVar , Var
3434
@@ -387,6 +387,51 @@ def _compile_memo_components(
387387 )
388388
389389
390+ def _get_shared_components_recursive (
391+ component : BaseComponent ,
392+ rendered_components : dict [str , None ],
393+ all_import_dicts : list [ParsedImportDict ],
394+ ):
395+ """Get the shared components for a component and its children.
396+
397+ A shared component is a StatefulComponent that appears in 2 or more
398+ pages and is a candidate for writing to a common file and importing
399+ into each page where it is used.
400+
401+ Args:
402+ component: The component to collect shared StatefulComponents for.
403+ rendered_components: A dict to store the rendered shared components in.
404+ all_import_dicts: A list to store the imports of all shared components in.
405+ """
406+ for child in component .children :
407+ # Depth-first traversal.
408+ _get_shared_components_recursive (child , rendered_components , all_import_dicts )
409+
410+ # When the component is referenced by more than one page, render it
411+ # to be included in the STATEFUL_COMPONENTS module.
412+ # Skip this step in dev mode, thereby avoiding potential hot reload errors for larger apps
413+ if (
414+ isinstance (component , StatefulComponent )
415+ and component .references > 1
416+ and is_prod_mode ()
417+ ):
418+ # Reset this flag to render the actual component.
419+ component .rendered_as_shared = False
420+
421+ # Include dynamic imports in the shared component.
422+ if dynamic_imports := component ._get_all_dynamic_imports ():
423+ rendered_components .update (dict .fromkeys (dynamic_imports ))
424+
425+ # Include custom code in the shared component.
426+ rendered_components .update (component ._get_all_custom_code (export = True ))
427+
428+ # Include all imports in the shared component.
429+ all_import_dicts .append (component ._get_all_imports ())
430+
431+ # Indicate that this component now imports from the shared file.
432+ component .rendered_as_shared = True
433+
434+
390435def _compile_stateful_components (
391436 page_components : list [BaseComponent ],
392437) -> str :
@@ -406,46 +451,10 @@ def _compile_stateful_components(
406451 all_import_dicts = []
407452 rendered_components = {}
408453
409- def get_shared_components_recursive (component : BaseComponent ):
410- """Get the shared components for a component and its children.
411-
412- A shared component is a StatefulComponent that appears in 2 or more
413- pages and is a candidate for writing to a common file and importing
414- into each page where it is used.
415-
416- Args:
417- component: The component to collect shared StatefulComponents for.
418- """
419- for child in component .children :
420- # Depth-first traversal.
421- get_shared_components_recursive (child )
422-
423- # When the component is referenced by more than one page, render it
424- # to be included in the STATEFUL_COMPONENTS module.
425- # Skip this step in dev mode, thereby avoiding potential hot reload errors for larger apps
426- if (
427- isinstance (component , StatefulComponent )
428- and component .references > 1
429- and is_prod_mode ()
430- ):
431- # Reset this flag to render the actual component.
432- component .rendered_as_shared = False
433-
434- # Include dynamic imports in the shared component.
435- if dynamic_imports := component ._get_all_dynamic_imports ():
436- rendered_components .update (dict .fromkeys (dynamic_imports ))
437-
438- # Include custom code in the shared component.
439- rendered_components .update (component ._get_all_custom_code (export = True ))
440-
441- # Include all imports in the shared component.
442- all_import_dicts .append (component ._get_all_imports ())
443-
444- # Indicate that this component now imports from the shared file.
445- component .rendered_as_shared = True
446-
447454 for page_component in page_components :
448- get_shared_components_recursive (page_component )
455+ _get_shared_components_recursive (
456+ page_component , rendered_components , all_import_dicts
457+ )
449458
450459 # Don't import from the file that we're about to create.
451460 all_imports = utils .merge_imports (* all_import_dicts )
0 commit comments