As I said, it's not easy for me to explain better than the last given sentence. Each time x() changes, a new nested observer is created. The first one performs print(x), the second one as well, etc. Each one prints the value of x.
The code below shows that there are three nested observers at the end, but there's another difficulty, namely understanding local().
library(shiny)
reactiveConsole(TRUE)
x <- reactiveVal(1)
i <- 0
observe({
x()
i <<- i + 1
local({
j <- i
observe({
x()
print(paste("Hello I am the nested observer", j))
})
})
})
# [1] "Hello I am the nested observer 1"
# > x(12)
# [1] "Hello I am the nested observer 1"
# [1] "Hello I am the nested observer 2"
# > x(16)
# [1] "Hello I am the nested observer 1"
# [1] "Hello I am the nested observer 2"
# [1] "Hello I am the nested observer 3"
Think about this one too:
x <- reactiveVal(1)
observe({
x()
local({
y <- x()
observe({
x()
print(y)
})
})
})
# [1] 1
# > x(5)
# [1] 1
# [1] 5
# > x(9)
# [1] 1
# [1] 5
# [1] 9
This other example is instructive as well:
x <- reactiveVal(10)
observe({
x()
observe({
req(x() >= 3)
print(x())
})
})
# [1] 10
# > x(2) # a new nested observer is created but it doesn't react because 2 < 3
# > x(1) # a new nested observer is created but it doesn't react because 1 < 3
# > x(4) # a new nested observer is created and it reacts because 4 >= 3
# [1] 4
# [1] 4
# [1] 4
# [1] 4