reflex-dev / reflex

🕸️ Web apps in pure Python 🐍

Home Page:https://reflex.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

When rx.cond and rx.accordian are used together, the open accordian is closed when the `value` prop in accordion Item is not set after applying deltas.

Evenzel opened this issue · comments

Describe the bug
When rx.cond and rx.accordian are used together, the open accordian is closed when rx.form is submitted.

To Reproduce

import reflex as rx


class TestState(rx.State):
    result: dict = {}

    def handle_submit(self, data):
        self.result = data


@rx.page(route="/")
def index():
    return rx.cond(
        TestState.is_hydrated,
        rx.vstack(
            rx.form(
                rx.vstack(
                    rx.accordion.root(
                        rx.accordion.item(
                            header='test',
                            content=rx.hstack(
                                rx.select(
                                    ["Yes", "No"],
                                    placeholder="Select an option",
                                    name="test_form",
                                    font_size="1em",
                                ),
                                rx.button("Submit", type_="submit"),
                            ),
                        ),
                        collapsible=True,
                    ),
                ),
                on_submit=TestState.handle_submit,
            ),
            rx.text(TestState.result['test_form'])
        ),
        rx.chakra.spinner(),
    )


app = rx.App()

Expected behavior
accordian should not be closed.

Screenshots

  1. Before submit
    image

  2. After submit
    image

Specifics (please complete the following information):

  • Python Version: 3.11.4
  • Reflex Version: 0.4.7
  • OS: Windows 10
  • Browser (Optional): Chrome

Additional context
Add any other context about the problem here.

I've played around this a bit and I suspect this might be a radix bug(would need further investigations to conclude). For AccordionItem, we generate a random value for the value prop which is required by radix and is used in controlling the item based on the trigger. For some weird reason when state value changes (or deltas are applied after an event handler is triggered), the accordion item doesn't maintain its state(open/closed). This would require some further investigations into how radix treats the value prop since they don't seem to render the value prop in the DOM. But this behavior seems to show up when the accordion is in a conditional.

Even without the form, this is enough to repro:

import reflex as rx


class TestState(rx.State):
    val : bool = True
    num: int = 0

    def increment(self):
        self.num += 1


@rx.page(route="/")
def index():
    return rx.cond(
        TestState.val,
        rx.vstack(
            rx.text(TestState.num),
            rx.button("incremment", on_click=TestState.increment),
            rx.vstack(
                rx.accordion.root(
                    rx.accordion.item(
                        header='test',
                        content=rx.hstack(
                            rx.select(
                                ["Yes", "No"],
                                placeholder="Select an option",
                                name="test_form",
                                font_size="1em",
                            ),
                        ),
                    ),
                    collapsible=True,
                ),
            ),
        ),
        rx.chakra.spinner(),
    )

A workaround will be to provide a value for the accordion item:

...
rx.accordion.root(
    rx.accordion.item(
          header='test',
          content=rx.hstack(
                            rx.select(
                                ["Yes", "No"],
                                placeholder="Select an option",
                                name="test_form",
                                font_size="1em",
                            ),
                            rx.button("Submit", type_="submit"),
          ),
         value="item1" # provide a value 
   ),
  collapsible=True,
),

A workaround will be to provide a value for the accordion item:

does this have to be a predefined state value or can it just be any old string, i ask because you defined value = "item1" but item1 was never mentioned anywhere in the provided snippet

A workaround will be to provide a value for the accordion item:

does this have to be a predefined state value or can it just be any old string, i ask because you defined value = "item1" but item1 was never mentioned anywhere in the provided snippet

Yes, value can be any arbitrary string

Since the UUID is generated on the frontend rather than during compilation, state changes which trigger a re-render will generate a new UUID, so the currently open tabs don't match anymore.