Skip to content

[Bug]: Unexpected reactive value update behaviour #1949

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pieterjanvc opened this issue Apr 1, 2025 · 1 comment
Closed

[Bug]: Unexpected reactive value update behaviour #1949

pieterjanvc opened this issue Apr 1, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@pieterjanvc
Copy link

Component

Reactive Programming

Severity

P2 - Medium (workaround exists)

Shiny Version

1.3.0

Python Version

3.11.1

Minimal Reproducible Example

from shiny import App, reactive, render, ui

app_ui = ui.page_fluid(
    ui.input_action_button("add", "add"),
    ui.input_action_button("remove", "remove"),
    ui.output_text("info")
)

def server(input, output, session):

    check = reactive.value([0])

    @reactive.effect()
    @reactive.event(input.add)
    def _():
        check.set(check() + [input.add()])

    @reactive.effect()
    @reactive.event(input.remove)
    def _():
        x = check()
        _ = x.pop()
        print(x)
        check.set(x)
        print(check())
    
    @render.text
    def info():
        return f"The value is {check()}"

app = App(app_ui, server)

Behavior

Add function works as expected

In the example above, clicking the add button will add a number to the list and the text output will update as expected.

Remove function unexpected effect

When clicking the remove button, the reactive variable is updated (see console output), but nothing is triggered so the UI won't update until another process like the add button shows the new output.

Explanation

The reason is that x = check() is not making a copy of the reactive value, but just transferring the ownership, which is normal python behaviour. However, the fact that it is then possible to actually update the reactive variable but not evoking a trigger, is unexpected and counterintuitive. I suggest this should either result in an error, or propagate as expected.

When using x = check().clone() instead, the app works as expected. Again, I would argue this is the correct syntax, but the shown alternative should not allow to silently change the reactive variable without a trigger.

Error Messages (if any)

Environment

Windows 10
Chrome
@pieterjanvc pieterjanvc added the bug Something isn't working label Apr 1, 2025
@schloerke
Copy link
Collaborator

👋 @pieterjanvc

This bug is a feature.

As you said, you can use .clone() to produce a new points. You may also get around it by calling check.unset() before you call check.set(value). Example app

Please see https://shiny.posit.co/py/docs/reactive-mutable.html for more details

(Closing)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants