-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Deprecate freezeReactiveVal, and freezeReactiveValue for non-inputs #3063
Comments
FYI a GitHub search for "freezeReactiveVal" in R code resulted in 0 hits outside of shiny source code. For reference, "freezeReactiveValue" did have real usages found on GitHub. This isn't conclusive evidence, but helps support your claim that it probably isn't used much https://github.com/search?l=R&q=freezeReactiveVal&type=Code |
shiny 1.6.0 ================ This release focuses on improvements in three main areas: 1. Better theming (and Bootstrap 4) support: * The `theme` argument of `fluidPage()`, `navbarPage()`, and `bootstrapPage()` all now understand `bslib::bs_theme()` objects, which can be used to opt-into Bootstrap 4, use any Bootswatch theme, and/or implement custom themes without writing any CSS. * The `session` object now includes `$setCurrentTheme()` and `$getCurrentTheme()` methods to dynamically update (or obtain) the page's `theme` after initial load, which is useful for things such as [adding a dark mode switch to an app](https://rstudio.github.io/bslib/articles/theming.html#dynamic-shiny) or some other "real-time" theming tool like `bslib::bs_themer()`. * For more details, see [`{bslib}`'s website](https://rstudio.github.io/bslib/) 2. Caching of `reactive()` and `render*()` (e.g. `renderText()`, `renderTable()`, etc) expressions. * Such expressions automatically cache their _most recent value_, which helps to avoid redund ant computation within a single "flush" of reactivity. The new `bindCache()` function can be used to cache _all previous values_ (as long as they fit in the cache). This cache may be optionally scoped within and/or across user sessions, possibly leading to huge performance gains, especially when deployed at scale across user sessions. * For more details, see `help(bindCache, package = "shiny")` 3. Various improvements to accessibility for screen-reader and keyboard users. * For more details, see the accessibility section below. ## Full changelog ### Breaking changes * Closed #3074: Shiny no longer supports file uploads for Internet Explorer 8 or 9. (#3075) * Subtle changes, and some soft-deprecations, have come to `freezeReactiveValue` and `freezeReactiveVal` (#3055). These functions have been fragile at best in previous releases (issues #1791, #2463, #2946). In this release, we've solved all the problems we know about with `freezeReactiveValue(input, "x")`, by 1) invalidating `input$x` and set it to `NULL` whenever we freeze, and 2) ensuring that, after a freeze, even if the effect of `renderUI` or `updateXXXInput` is to set `input$x` to the same value it already has, this will result in an invalidation (whereas by default, Shiny filters out such spurious assignments). Similar problems may exist when using `freezeReactiveVal`, and when using `freezeReactiveValue` with non-`input` reactive values objects. But support for those was added mostly for symmetry with `freezeReactiveValue(input)`, and given the above issues, it's not clear to us how you could have used these successfully in the past, or why you would even want to. For this release, we're soft-deprecating both of those uses, but we're more than willing to un-deprecate if it turns out people are using these; if that includes you, please join the conversation at rstudio/shiny#3063. In the meantime, you can squelch the deprecation messages for these functions specifically, by setting `options(shiny.deprecation.messages.freeze = FALSE)`. ### Accessibility * Added [bootstrap accessibility plugin](https://github.com/paypal/bootstrap-accessibility-plugin) under the hood to improve accessibility of shiny apps for screen-reader and keyboard users: the enhancements include better navigations for alert, tooltip, popover, modal dialog, dropdown, tab Panel, collapse, and carousel elements. (#2911) * Closed #2987: Improved accessibility of "live regions" -- namely, `*Output()` bindings and `update*Input()`. (#3042) * Added appropriate labels to `icon()` element to provide screen-reader users with alternative descriptions for the `fontawesome` and `glyphicon`: `aria-label` is automatically applied based on the fontawesome name. For example, `icon("calendar")` will be announced as "calendar icon" to screen readers. "presentation" aria role has also been attached to `icon()` to remove redundant semantic info for screen readers. (#2917) * Closed #2929: Fixed keyboard accessibility for file picker button: keyboard users can now tab to focus on `fileInput()` widget. (#2937) * Fixed #2951: screen readers correctly announce labels and date formats for `dateInput()` and `dateRangeInput()` widgets. (#2978) * Closed #2847: `selectInput()` is reasonably accessible for screen readers even when `selectize` option is set to TRUE. To improve `selectize.js` accessibility, we have added [selectize-plugin-a11y](https://github.com/SLMNBJ/selectize-plugin-a11y) by default. (#2993) * Closed #612: Added `alt` argument to `renderPlot()` and `renderCachedPlot()` to specify descriptive texts for `plotOutput()` objects, which is essential for screen readers. By default, alt text is set to the static text, "Plot object," but even dynamic text can be made with reactive function. (#3006, thanks @trafficonese and @leonawicz for the original PR and discussion via #2494) * Added semantic landmarks for `mainPanel()` and `sidebarPanel()` so that assistive technologies can recognize them as "main" and "complementary" region respectively. (#3009) * Closed #2844: Added `lang` argument to ui `*Page()` functions (e.g., `fluidPage`, `bootstrapPage`) that specifies document-level language within the app for the accessibility of screen readers and search-engine parsers. By default, it is set to empty string which is commonly recognized as a browser's default locale. (#2920) * Improved accessibility for `radioButtons()` and `checkboxGroupInput()`: All options are now grouped together semantically for assistive technologies. (thanks @jooyoungseo, #3187). ### Minor new features and improvements * Added support for Shiny Developer Mode. Developer Mode enables a number of `options()` to make a developer's life easier, like enabling non-minified JS and printing messages about deprecated functions and options. See `?devmode()` for more details. (#3174) * New `reactiveConsole()` makes it easier to interactively experiment with reactivity at the console (#2518). * When UI is specified as a function (e.g. `ui <- function(req) { ... }`), the response can now be an HTTP response as returned from the (newly exported) `httpResponse()` function. (#2970) * `selectInput` and `selectizeInput` now warn about performance implications when thousands of choices are used, and recommend [server-side selectize](https://shiny.rstudio.com/articles/selectize.html) be used instead. (#2959) * Closed #2980: `addResourcePath()` now allows paths with a leading `.` (thanks to @ColinFay). (#2981) * Closed #2972: `runExample()` now supports the `shiny.port` option (thanks to @ColinFay). (#2982) * Closed #2692: `downloadButton()` icon can now be changed via the `icon` parameter (thanks to @ColinFay). (#3010) * Closed #2984: improved documentation for `renderCachedPlot()` (thanks to @aalucaci). (#3016) * `reactiveValuesToList()` will save its `reactlog` label as `reactiveValuesToList(<ID>)` vs `as.list(<ID>)` (#3017) * Removed unused (and non-exported) `cacheContext` class. * `testServer()` can accept a single server function as input (#2965). * `shinyOptions()` now has session-level scoping, in addition to global and application-level scoping. (#3080) * `runApp()` now warns when running an application in an R package directory. (#3114) * Shiny now uses `cache_mem` from the cachem package, instead of `memoryCache` and `diskCache`. (#3118) * Closed #3140: Added support for `...` argument in `icon()`. (#3143) * Closed #629: All `update*` functions now have a default value for `session`, and issue an informative warning if it is missing. (#3195, #3199) * Improved error messages when reading reactive values outside of a reactive domain (e.g., `reactiveVal()()`). (#3007) ### Bug fixes * Fixed #1942: Calling `runApp("app.R")` no longer ignores options passed into `shinyApp()`. This makes it possible for Shiny apps to specify what port/host should be used by default. (#2969) * Fixed #3033: When a `DiskCache` was created with both `max_n` and `max_size`, too many items could get pruned when `prune()` was called. (#3034) * Fixed #2703: Fixed numerous issues with some combinations of `min`/`value`/`max` causing issues with `date[Range]Input()` and `updateDate[Range]Input()`. (#3038, #3201) * Fixed #2936: `dateYMD` was giving a warning when passed a vector of dates from `dateInput` which was greater than length 1. The length check was removed because it was not needed. (#3061) * Fixed #2266, #2688: `radioButtons` and `updateRadioButtons` now accept `character(0)` to indicate that none of the options should be selected (thanks to @ColinFay). (#3043) * Fixed a bug that `textAreaInput()` doesn't work as expected for relative `width` (thanks to @shrektan). (#2049) * Fixed #2859: `renderPlot()` wasn't correctly setting `showtext::showtext_opts()`'s `dpi` setting with the correct resolution on high resolution displays; which means, if the font was rendered by showtext, font sizes would look smaller than they should on such displays. (#2941) * Closed #2910, #2909, #1552: `sliderInput()` warns if the `value` is outside of `min` and `max`, and errors if `value` is `NULL` or `NA`. (#3194) ### Library updates * Removed html5shiv and respond.js, which were used for IE 8 and IE 9 compatibility. (#2973) * Removed es5-shim library, which was internally used within `selectInput()` for ECMAScript 5 compatibility. (#2993) shiny 1.5.0 =========== ## Full changelog ### Breaking changes * Fixed #2869: Until this release, `renderImage()` had a dangerous default of `deleteFile = TRUE`. (Sorry!) Going forward, calls to `renderImage()` will need an explicit `deleteFile` argument; for now, failing to provide one will result in a warning message, and the file will be deleted if it appears to be within the `tempdir()`. (#2881) ### New features * The new `shinyAppTemplate()` function creates a new template Shiny application, where components are optional, such as helper files in an R/ subdirectory, a module, and various kinds of tests. (#2704) * `runTests()` is a new function that behaves much like R CMD check. `runTests()` invokes all of the top-level R files in the tests/ directory inside an application, in that application's environment. (#2585) * `testServer()` is a new function for testing reactive behavior inside server functions and modules. ([#2682](rstudio/shiny#2682), [#2764](rstudio/shiny#2764), [#2807](rstudio/shiny#2807)) * The new `moduleServer` function provides a simpler interface for creating and using modules. (#2773) * Resolved #2732: `markdown()` is a new function for writing Markdown with Github extensions directly in Shiny UIs. Markdown rendering is performed by the [commonmark](https://github.com/jeroen/commonmark) package. (#2737) * The `getCurrentOutputInfo()` function can now return the background color (`bg`), foreground color (`fg`), `accent` (i.e., hyperlink) color, and `font` information of the output's HTML container. This information is reported by `plotOutput()`, `imageOutput()`, and any other output bindings containing a class of `.shiny-report-theme`. This feature allows developers to style an output's contents based on the container's CSS styling. (#2740) ### Minor new features and improvements * Fixed #2042, #2628: In a `dateInput` and `dateRangeInput`, disabled months and years are now a lighter gray, to make it easier to see that they are disabled. (#2690) * `getCurrentOutputInfo()` previously threw an error when called from outside of an output; now it returns `NULL`. (#2707 and #2858) * Added a label to observer that auto-reloads `R/` directory to avoid confusion when using `reactlog`. (#58) * `getDefaultReactiveDomain()` can now be called inside a `session$onSessionEnded` callback and will return the calling `session` information. (#2757) * Added a `'function'` class to `reactive()` and `reactiveVal()` objects. (#2793) * Added a new option (`type = "hidden"`) to `tabsetPanel()`, making it easier to set the active tab via other input controls (e.g., `radioButtons()`) rather than tabs or pills. Use this option in conjunction with `updateTabsetPanel()` and the new `tabsetPanelBody()` function (see `help(tabsetPanel)` for an example and more details). (#2814) * Added function `updateActionLink()` to update an `actionLink()` label and/or icon value. (#2811) * Fixed #2856: Bumped jQuery 3 from 3.4.1 to 3.5.1. (#2857) ### Bug fixes * Fixed #2606: `debounce()` would not work properly if the code in the reactive expression threw an error on the first run. (#2652) * Fixed #2653: The `dataTableOutput()` could have incorrect output if certain characters were in the column names. (#2658) ### Documentation Updates ### Library updates * Updated from Font-Awesome 5.3.1 to 5.13.0, which includes icons related to COVID-19. For upgrade notes, see https://github.com/FortAwesome/Font-Awesome/blob/master/UPGRADING.md. (#2891) shiny 1.4.0.2 =========== Minor patch release: fixed some timing-dependent tests failed intermittently on CRAN build machines. shiny 1.4.0.1 =========== Minor patch release to account for changes to the grid package that will be upcoming in the R 4.0 release (#2776). shiny 1.4.0 =========== ## Full changelog ### Breaking changes * Resolved #2554: Upgraded jQuery from v.1.12.4 to v3.4.1 and bootstrap from v3.3.7 to v3.4.1. (#2557). Since the jQuery upgrade may introduce breaking changes to user code, there is an option to switch back to the old version by setting `options(shiny.jquery.version = 1)`. If you've hard-coded `shared/jquery[.min].js` in the HTML of your Shiny app, in order to downgrade, you'll have to change that filepath to `shared/legacy/jquery[.min].js`. ### Improvements * Resolved #1433: `plotOutput()`'s coordmap info now includes discrete axis limits for **ggplot2** plots. As a result, any **shinytest** tests that contain **ggplot2** plots with discrete axes (that were recorded before this change) will now report differences that can safely be updated. This new coordmap info was added to correctly infer what data points are within an input brush and/or near input click/hover in scenarios where a non-trivial discrete axis scale is involved (e.g., whenever `scale_[x/y]_discrete(limits = ...)` and/or free scales across multiple discrete axes are used). (#2410) * Resolved #2402: An informative warning is now thrown for mis-specified (date) strings in `dateInput()`, `updateDateInput()`, `dateRangeInput()`, and `updateDateRangeInput()`. (#2403) * If the `shiny.autoload.r` option is set to `TRUE`, all files ending in `.r` or `.R` contained in a directory named `R/` adjacent to your application are sourced when your app is started. This will become the default Shiny behavior in a future release (#2547) * Resolved #2442: The `shiny:inputchanged` JavaScript event now triggers on the related input element instead of `document`. Existing event listeners bound to `document` will still detect the event due to event bubbling. (#2446) * Fixed #1393, #2223: For plots with any interactions enabled, the image is no longer draggable. (#2460) * Resolved #2469: `renderText` now takes a `sep` argument that is passed to `cat`. (#2497) * Added `resourcePaths()` and `removeResourcePaths()` functions. (#2459) * Resolved #2433: An informative warning is now thrown if subdirectories of the app's `www/` directory are masked by other resource prefixes and/or the same resource prefix is mapped to different local file paths. (#2434) * Resolved #2478: `cmd + shift + f3` and `ctrl + shift + f3` can now be used to add a reactlog mark. If reactlog keybindings are used and the reactlog is not enabled, an error page is displayed showing how to enable reactlog recordings. (#2560) ### Bug fixes * Partially resolved #2423: Reactivity in Shiny leaked some memory, because R can leak memory whenever a new symbols is interned, which happens whenever a new name/key is used in an environment. R now uses the fastmap package, which avoids this problem. (#2429) * Fixed #2267: Fixed a memory leak with `invalidateLater`. (#2555) * Fixed #1548: The `reactivePoll` function leaked an observer; that is the observer would continue to exist even if the `reactivePoll` object was no longer accessible. #2522 * Fixed #2116: Fixed an issue where dynamic tabs could not be added when on a hosted platform. (#2545) * Resolved #2515: `selectInput()` and `selectizeInput()` now deal appropriately with named factors. Note that `updateSelectInput()` and `updateSelectizeInput()` **do not** yet handle factors; their behavior is unchanged. (#2524, #2540, #2625) * Resolved #2471: Large file uploads to a Windows computer were slow. (#2579) * Fixed #2387: Updating a `sliderInput()`'s type from numeric to date no longer changes the rate policy from debounced to immediate. More generally, updating an input binding with a new type should (no longer) incorrectly alter the input rate policy. (#2404) * Fixed #868: If an input is initialized with a `NULL` label, it can now be updated with a string. Moreover, if an input label is initialized with a string, it can now be removed by updating with `label=character(0)` (similar to how `choices` and `selected` can be cleared in `updateSelectInput()`). (#2406) * Fixed #2250: `updateSliderInput()` now works with un-specified (or zero-length) `min`, `max`, and `value`. (#2416) * Fixed #2396: `selectInput("myID", ...)` resulting in an extra `myID-selectized` input (introduced in v1.2.0). (#2418) * Fixed #2233: `verbatimTextOutput()` produced wrapped text on Safari, but the text should not be wrapped. (#2353) * Fixed #2335: When `dateInput()`'s `value` was unspecified, and `max` and/or `min` was set to `Sys.Date()`, the value was not being set properly. (#2526) * Fixed #2591: Providing malformed date-strings to `min` or `max` no longer results in JS errors for `dateInput()` and `dateRangeInput()`. (#2592) * Fixed [rstudio/reactlog#36](rstudio/reactlog#36): Changes to reactive values not displaying accurately in reactlog. (#2424) * Fixed #2598: Showcase files don't appear with a wide window. (#2582) * Fixed #2329, #1817: These bugs were reported as fixed in Shiny 1.3.0 but were not actually fixed because some JavaScript changes were accidentally not included in the release. The fix resolves issues that occur when `withProgressBar()` or bookmarking are combined with the [networkD3](https://christophergandrud.github.io/networkD3/) package's Sankey plot.
I'll admit this is not something used a lot in shiny but I have a lot of apps that follow this pattern. I make the update client-side and want to keep the underlying reactive in-sync but not re-render the whole thing. library(shiny)
js <- "
const deleteListen = () => {
$('.delete').off();
$('.delete').on('click', (e) => {
// get parent
let $el = $(e.target).closest('.el');
// get row index and remove
let index = $el.data('index');
$el.remove();
// send to server
Shiny.setInputValue('deleted', index);
});
}
Shiny.addCustomMessageHandler('update-data', (msg) => {
console.log(msg);
let cnt = '';
msg.forEach((row, index) => {
cnt += `<div data-index='${index}' class='el'>
<span>Speed: ${row.speed}</span>
<span>Dist: ${row.dist}</span>
<button class='delete'>delete</button>
</div>`;
});
$('#ui').html(cnt);
deleteListen()
});
"
ui <- fluidPage(
tags$head(
tags$style(
".el {
border:1px solid black;
padding:1rem;
margin:1rem;
}"
),
tags$script(HTML(js))
),
div(id = "ui")
)
server <- function(input, output, session) {
cars_r <- reactiveVal(cars)
# 1. need to be inside observe to send message
# 2. this reactive may be updated elsehwere
# in the app: then we want to re-render
observeEvent(cars_r(), {
session$sendCustomMessage(
"update-data",
apply(cars_r(), 1, as.list)
)
})
observeEvent(input$deleted, {
# freeze
# I don't want to trigger the observe event above
# and re-render everything
# no need it's already removed from UI
freezeReactiveVal(cars_r)
new_cars <- cars_r()[-input$deleted]
})
}
shinyApp(ui, server) I know we can achieve something like this with the user of another reactive to selectively trigger the rendering but this can become very messy (I find) for larger applciations. Any suggestion to avoid freezing anything here is most welcome! |
@JohnCoene: Can you avoid freezing with two |
I have 2 views on my data, one as datatable(DT) and the other graphical(plotly). Stuff happens by selecting a object(cell) in the table. I want to allow user to select using the graph and I am sending the object name with Shiny.setInputValue js. My first attempt is to update input$dttable_cells_selected but that is not allowed. To make the story short, I add a layer of reactiveValues. When the user clicks an object in the graph, I need to udpate the table on top of all the other actions because the selected object may not be on the current page (DT::selectCells/DT::selectRows are used). My implementation is not stable as I am seeing asserting failures -- object cannot be located in the table unexpectedly. Btw, I have been doing more serious work with shiny and R for only a few months(start using env and did not know the difference between pandas and R dataframe a few months back) and know virtually nothing about html/js/css. I am comfortable with reactive programming because I do complex pipelines with gnu make for many years. I suspect the issue is that shiny dispatch mechanism is using 'input' snapshot(including reactive expressions I created and updated in the current cycle) -- where with make I see the updates immediately from the file system. I think I may have to 'freeze' the additional layer of reactiveValues(outside input) to ensure the datatable view is updated before the actions I normally run by selecting the table cell. I do not know if I am on the right path and have yet to dive into what is really happening with the crash/assertion failure. In summary: plotly input | table input -> non-input reactiveValues -> action based on table selection |
@GDCCP I'd suggest to split up the issue library-wise {DT}/{plotly} to create minimal reproducible examples and post them here or here. Cheers |
Noted. However, I probably cannot have a working implementation soon, or ever. Try to summarize briefly here. This is a server DT table and actions are triggered cell/row selection, i.e. changing variables like input$table_rows_selected and input$table_rows_current The enhancement is to tigger the action by clicking an object in a plotly graph (which maps to a string in say input$fig_plotly_clicked). I was trying to map this string back to a valid row number and make the call to DT::selectRows using the tableProxy, and trigger a change in the input$table_rows_selected and input$table_rows_current, I imagine, in my calls to DT::selectRows and DT::selectPage (without explict reading anything related to the DT table). I am also using DT filter='top' option, and numeric page input. I am now wondering if my use case is really supported. |
Consider getting rid of
freezeReactiveVal
, andfreezeReactiveValue
for non-input
objects. If you're using these functions and seeing a deprecation message, please add a comment to this issue--we want to know what you're doing!The need for
freezeReactiveValue(input, "x")
is clear. Whenserver
calls for changes to an input on the client side, viarenderUI
with inputs inside, orupdateXXXInput
, orinsertUI
, it's likely that the input's current value is, temporarily, no longer useful or even dangerous (in that it might be inconsistent with other input state that has already been updated).freezeReactiveValue
prevents outputs from rendering an error during this window of time.The need to use
freezeReactiveVal
, orfreezeReactiveValue
with a genericreactiveValues
object, is far less clear. I think we implemented it for "consistency" but there's nothing consistent about these use cases, and it's not clear to me that you could effectively use them today if you wanted to (especially, the "automatically thaw ononFlushed
" seems wrong to me now).We could fix the semantics of these functions so they can actually be used, but I'm inclined to proceed cautiously because 1) I'm still not sure what scenario exists where you'd actually want to use it, and 2) in case someone has somehow figured out a way to use the current implementation to do something useful, we'd be breaking them.
I propose we soft-deprecate these uses, and have the deprecation warning message include a link to this issue. If people are actually using these functions then we can consider un-deprecating.
The text was updated successfully, but these errors were encountered: