Repository: reflex-dev/reflex

Issue:
rx.match takes exceedingly long time with many cases
Describe the bug
I reproduced this bug by accident when I was making an rx.match and there were a large number of elements
Link: [old issues](https://github.com/reflex-dev/reflex/issues/4676)

To Reproduce
Steps to reproduce the behavior:

Copy the code and check
Expected behavior
0:01 render, in fact, 1 minute and 13 seconds

Video:
[https://youtu.be/BAU1vC67-To](https://youtu.be/BAU1vC67-To)


Discussion:
<p><a href="https://linear.app/reflex-dev/issue/ENG-4510/rxmatch-takes-exceedingly-long-time-with-many-cases">ENG-4510 rx.match takes exceedingly long time with many cases</a></p>
GitHub: https://github.com/oReazy/AMPR-bug
This phenomenon, as I understood from the last report, is manifested due to rx.foreach, although I'm not very sure, but you have the entire code base and you can build the project yourself.

The main thing here is not the availability of a database, but the time to build the project.

As shown in the video, the code is in AMPR\pages\base\inventory.py, 528 line and 568


The array of items in foreach is not huge, i.e. 3-4 items are used for tests. These items are in the database.

Is there a need for a database?
I'm hitting it locally with:
```py
import reflex as rx


all_icons = [
    "tree-deciduous",
    "brick-wall",
    "gift",
    "leaf",
    "box",
    "wheat",
    "apple",
    "pizza",
    "ham",
    "egg",
    "egg-fried",
    "cake-slice",
    "banana",
    "martini",
    "ice-cream-cone",
    "glass-water",
    "soup",
    "wine",
    "gem",
    "codesandbox",
    "briefcase",
]


def shuffled(arr: list[str]):
    import random

    arr = arr.copy()
    random.shuffle(arr)
    return arr


class State(rx.State):
    names_list: list[list[str]] = []


def icon(name: str, size: int = 30):
    return rx.icon(tag=name, size=size)


def match_cases(names: list[str]):
    return [(name, icon(name)) for name in names]


def index():
    return rx.foreach(
        State.names_list,
        lambda names: rx.foreach(
            names, lambda name: rx.match(name, *match_cases(all_icons * 2))
        ),
    )


app = rx.App()
app.add_page(index, "/")
app._compile()
```
I will figure it out soon :+1:
Thanks for the catch. It found some nasty code.



Patch:
diff --git a/reflex/.templates/jinja/web/pages/utils.js.jinja2 b/reflex/.templates/jinja/web/pages/utils.js.jinja2
index 624e3bee862..567ca6e602b 100644
--- a/reflex/.templates/jinja/web/pages/utils.js.jinja2
+++ b/reflex/.templates/jinja/web/pages/utils.js.jinja2
@@ -90,7 +90,7 @@
                 break;
         {% endfor %}
             default:
-                return {{ component.default }};
+                return {{ render(component.default) }};
                 break;
         }
     })()
diff --git a/reflex/components/tags/tag.py b/reflex/components/tags/tag.py
index 0587c61eda8..d6bb7d2ca46 100644
--- a/reflex/components/tags/tag.py
+++ b/reflex/components/tags/tag.py
@@ -65,7 +65,24 @@ def __iter__(self):
         Yields:
             Tuple[str, Any]: The field name and value.
         """
+        from reflex.components.component import BaseComponent
+
         for field in dataclasses.fields(self):
+            value = getattr(self, field.name)
+            if isinstance(value, list):
+                children = []
+                for child in value:
+                    if isinstance(child, BaseComponent):
+                        children.append(child.render())
+                    else:
+                        children.append(child)
+                yield field.name, children
+                continue
+            if isinstance(value, BaseComponent):
+                yield field.name, value.render()
+                continue
+            if callable(value) and not isinstance(value, Var):
+                continue
             yield field.name, getattr(self, field.name)
 
     def add_props(self, **kwargs: Optional[Any]) -> Tag:


Test patch:
diff --git a/tests/units/components/core/test_match.py b/tests/units/components/core/test_match.py
index e563873ec83..b765750eeb9 100644
--- a/tests/units/components/core/test_match.py
+++ b/tests/units/components/core/test_match.py
@@ -78,7 +78,7 @@ def test_match_components():
     assert fifth_return_value_render["name"] == "RadixThemesText"
     assert fifth_return_value_render["children"][0]["contents"] == '{"sixth value"}'
 
-    default = match_child["default"].render()
+    default = match_child["default"]
 
     assert default["name"] == "RadixThemesText"
     assert default["children"][0]["contents"] == '{"default value"}'
@@ -153,7 +153,7 @@ def test_match_on_component_without_default():
     match_comp = Match.create(MatchState.value, *match_case_tuples)
     default = match_comp.render()["children"][0]["default"]
 
-    assert isinstance(default, Fragment)
+    assert isinstance(default, dict) and default["name"] == Fragment.__name__
 
 
 def test_match_on_var_no_default():