Proposal for new feature: conditionalReactive #3298
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR proposes a new method that allows finer control over when an upstream, invalidated reactive should invalidate downstream reactives. Basically, it wraps
into
or, simply avoid triggering a downstream reactive if the input value has not change.
without the need of additional variables/reactives to keep track of new and old values.
Usage:
fire.on.NULL
andfire.on.NA
allows us to select different strategies if the new value isNULL
orNA
. In the first example (if (oldvalue != input$newvalue)
, if the new value isNULL
orNA
, the if-statement will error or not behave as expected (as the expression either returns a logical vector with length not-equal to 1, or simplyNA
). With these two arguments, the saves the user from hassle of checking forNA
s andNULL
s - while allowing them to decide e.g. whether aNULL
should be considered different from the previousNULL
.checkFun
allows us to fine-tune what is considered an inequality between the new and old value. One could decide that not only should the new value be different from the previous, but it should be different by a margin, before recalculating, i.e.Other scenarios:
Say a user must change 2 or more input values (e.g.
x
andy
) before allowing invalidating downstreams reactives:R6 classes, complex data structures, and side-effects
In instances where a recalculating can be computational consuming, shiny now offers
bindCache
. However, if the dependencies of the current reactive result are unclear (many, many inputs), listing these inbindCache
is not attractive.In cases of reference-like objects like R6, sharing the result among different users is a bad idea (i.e. don't cache if evaluation has side-effects).
Annoy your users
If you want to your users to click 3 times on an actionButton before moving on,
Avoids re-calculating old result when debounced
In DataTable, the user can select cells/rows/column, but if the input is combined with
debounce
, you can get situations where the input is re-sent with the same input, if a user selects then deselects the same item before the debounce fires. Additionally, for DataTable input, the input-reactive (e.g.input$dt_cells_selected
) isNULL
before the table is loaded, so any handling of the input has to deal withNULL
s before considering whether the action is worth updating e.g. a render.Comparison to existing features of Shiny
Some of these scenarios might be solves through the use of
req
,validate
, andbindCache
, but by wrapping the conditionality into a method allows the code to be more readable, and the method takes care of some of the recurring obstacles of dealing withNULL
s,NA
s, or inputs with different lengths.R CMD check
The pull request was checked with R version 4.0.3 on Windows 10 x64, and did not generate any additional errors (running R CMD check on master commit
60db1e02b03d8e6fb146c9bb1bbfbce269231add
generated the following failure