There is a catch, though it won't come into play in your example.
The shiny developers designed reactive()
to be lazy, meaning that the expression contained in it will only be executed when it is called by one of its dependents. When one of its reactive dependencies is changed, it clears its cache and notifies its own dependents, but it is not itself executed until asked to by one of those dependents. (So if, say, its sole dependent is a textOutput()
element on a hidden tab, it won't actually be executed unless and until that tab is opened.)
observe()
, on the other hand, is eager; the expression that it contains will be executed right away whenever one of its reactive dependencies is changed -- even if it's value is not needed by any of its dependents (and in fact even if has no dependents). Such eagerness is desirable when you're calling observe()
for its side-effects, but it can be wasteful when you're only using it to pass on the return value of its contents to other reactive expressions or endpoints down the line.
Joe Cheng explains this distinction quite well in his 2016 Shiny Developer Conference presentation on "Effective reactive programming", available here. See especially the bit starting around 30:20 in the presentation's second hour. If you watch until 40:42 (blink and you'll miss it!) he briefly characterizes the behavior of the observe()
/reactiveValue ()
combination that you like.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…