Approfondissement de la programmation réactive
Comprenez les valeurs réactives, les objets réactifs, les observateurs et le graphe réactif.
Approfondissement de la programmation réactive est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.
Réactivité : l’idée principale
Le modèle de programmation réactive de Shiny suit automatiquement les dépendances entre les calculs. Lorsqu’une entrée change, seules les sorties qui en dépendent sont réexécutées — rien de plus. Comprendre ce graphe de dépendances est essentiel pour écrire des applications Shiny efficaces et exemptes d’erreurs.
library(shiny)
# Simplest reactive relationship:
# output depends on input — Shiny tracks this automatically
server <- function(input, output, session) {
output$result <- renderText({
paste('You typed:', input$text_in) # depends on text_in
})
}reactive({}) — Calculs partagés
reactive({...}) crée une expression réactive dont le résultat est mis en cache et partagé. Si plusieurs sorties utilisent le même calcul coûteux, encapsulez-le dans reactive() afin de l’effectuer une seule fois par changement, plutôt qu’une fois par utilisateur. Appelez-la comme une fonction : data_subset().
server <- function(input, output, session) {
# Computed once, shared by multiple outputs
filtered_data <- reactive({
subset(mtcars, cyl == input$cyl_select)
})
output$plot <- renderPlot({ plot(filtered_data()$wt,
filtered_data()$mpg) })
output$table <- renderTable({ filtered_data() })
# filtered_data() is only recomputed once when cyl_select changes
}reactiveVal() — Valeur réactive unique
reactiveVal(initial_value) crée une variable réactive que vous pouvez lire et modifier par programmation. Lisez-la en l’appelant sans argument ; modifiez-la en l’appelant avec une nouvelle valeur. Cette fonction est utile pour stocker un état modifiable dont dépendent plusieurs observateurs ou sorties.
server <- function(input, output, session) {
counter <- reactiveVal(0) # initial value = 0
observeEvent(input$increment, {
counter(counter() + 1) # read current, write new
})
observeEvent(input$reset, {
counter(0) # reset to 0
})
output$count <- renderText(paste('Count:', counter()))
}reactiveValues() — Plusieurs variables d’état
reactiveValues(key = value, ...) fonctionne comme une liste nommée dont chaque élément est réactif. Lorsqu’un élément change, seules les sorties qui lisent cet élément sont invalidées. Utilisez cette fonction pour regrouper des variables d’état liées qui sont mises à jour ensemble.
server <- function(input, output, session) {
state <- reactiveValues(
data = NULL,
current_page = 1,
total_rows = 0
)
observeEvent(input$load_btn, {
state$data <- read.csv(input$file$datapath)
state$total_rows <- nrow(state$data)
state$current_page <- 1
})
output$info <- renderText({
paste('Page', state$current_page, '| Rows:', state$total_rows)
})
}observeEvent() — Réagir aux événements
observeEvent(eventExpr, handlerExpr) exécute handlerExpr chaque fois que eventExpr change. Il est utilisé pour les effets de bord : mettre à jour l’état, écrire dans une base de données, télécharger un fichier ou accéder à un onglet. Le gestionnaire ne renvoie aucune valeur.
server <- function(input, output, session) {
observeEvent(input$save_btn, {
# Runs once each time save_btn is clicked
write.csv(current_data(), '/tmp/export.csv', row.names = FALSE)
showNotification('Saved!', type = 'message')
})
observeEvent(input$reset_btn, {
updateTextInput(session, 'search', value = '')
updateSliderInput(session, 'range', value = c(0, 100))
})
}eventReactive() — Valeur à la demande
eventReactive(eventExpr, valueExpr) fonctionne comme reactive(), mais ne recalcule la valeur que lorsqu’un événement précis se produit (par exemple, un clic sur un bouton), et non à chaque modification de ses dépendances. Utilisez-le pour n’exécuter des calculs coûteux qu’à la demande explicite de l’utilisateur.
server <- function(input, output, session) {
# Only re-run the model when 'Run Model' is clicked
model_result <- eventReactive(input$run_btn, {
# Expensive computation — only on button click
lm(as.formula(input$formula), data = get(input$dataset))
})
output$summary <- renderPrint({
summary(model_result())
})
}isolate() — Lire sans créer de dépendance
isolate({expr}) lit une valeur ou une expression réactive sans établir de dépendance réactive. Le calcul environnant ne sera NOT réexécuté lorsque la valeur isolée change. Utilisez-le dans observe() ou observeEvent() pour accéder à l’état actuel sans vous abonner aux changements.
server <- function(input, output, session) {
observeEvent(input$add_row_btn, {
# Read current_data without depending on it
current <- isolate(data_rv())
new_row <- data.frame(
id = nrow(current) + 1,
value = input$new_value
)
data_rv(rbind(current, new_row))
})
}invalidateLater() — Actualisation automatique
Placé dans un contexte réactif, invalidateLater(ms) planifie sa réexécution après ms millisecondes. Cette fonction sert à effectuer des interrogations périodiques : actualiser un flux de données en direct, mettre à jour une horloge ou vérifier régulièrement l’arrivée de nouvelles lignes dans une base de données.
server <- function(input, output, session) {
live_data <- reactive({
invalidateLater(5000) # re-run every 5 seconds
# Fetch fresh data from external source
httr2::request('https://api.example.com/stats') |>
httr2::req_perform() |>
httr2::resp_body_json()
})
output$live_plot <- renderPlot({
plot(live_data()$time, live_data()$value, type = 'l')
})
}reactlog — Déboguer le graphe réactif
Le paquet reactlog visualise le graphe des dépendances réactives. Activez-le avant d’exécuter l’application, puis appelez reactlog_show() après vos interactions pour voir quels nœuds réactifs ont été invalidés et dans quel ordre. Il est indispensable pour déboguer les applications complexes.
library(reactlog)
# Enable reactlog BEFORE launching the app
reactlog_enable()
# Launch your app
shinyApp(ui, server)
# After interacting in the browser, in the R console:
shiny::reactlogShow()
# A viewer opens showing the reactive graph
# with timestamps and invalidation chainsAnti-modèle : isolation réactive
Une erreur fréquente consiste à lire accidentellement une valeur réactive dans un contexte non réactif, ou à créer des dépendances indésirables en lisant un réactif dans un calcul qui devrait être isolé. Soyez toujours attentif à l’endroit où vous créez des dépendances et à celui où vous lisez l’état comme un instantané ponctuel.
server <- function(input, output, session) {
# WRONG: output depends on input$name, but also re-runs
# every time input$slider changes (unintended dependency)
output$msg <- renderText({
paste(input$name, 'total:', input$slider * 2)
})
# CORRECT: output only responds to input$name changes;
# slider is read as a snapshot
output$msg_correct <- renderText({
slider_val <- isolate(input$slider)
paste(input$name, 'snapshot total:', slider_val * 2)
})
}observe() ou observeEvent()
observe({...}) crée un observateur réactif qui se réexécute automatiquement chaque fois qu’un réactif qu’il lit change. observeEvent(event, {...}) est plus contrôlé : il ne se déclenche qu’en réponse à un événement précis. Préférez observeEvent() pour les effets de bord déclenchés par des boutons afin d’éviter les réexécutions imprévues.
server <- function(input, output, session) {
# observe: re-runs on ANY change in input$x or input$y
observe({
cat('x or y changed:', input$x, input$y, '\n')
})
# observeEvent: only runs when button is clicked
observeEvent(input$submit_btn, {
cat('Form submitted with x =', isolate(input$x), '\n')
}, ignoreNULL = TRUE, ignoreInit = TRUE)
}Vérification rapide
Quelle est la différence essentielle entre reactive({}) et eventReactive(event, {}) ?
Récapitulatif de la programmation réactive
Points essentiels de l’approfondissement de la programmation réactive :
reactive({}): calcul mis en cache, réexécuté lorsque ses dépendances changent.reactiveVal(init): variable réactive mutable unique ; lecture avecval(), écriture avecval(new).reactiveValues(...): liste nommée de variables d’état réactives.observeEvent(event, {}): effets de bord déclenchés par un événement précis.eventReactive(event, {}): valeur calculée uniquement lorsqu’un événement précis se produit.isolate({}): lecture d’un réactif sans créer de dépendance.invalidateLater(ms): planification d’une réexécution périodique pour les mises à jour en direct.- Utilisez
reactlogpour visualiser et déboguer le graphe des dépendances réactives.
server <- function(input, output, session) {
# State
rv <- reactiveValues(data = NULL, n = 0)
# Load data on button click
observeEvent(input$load, {
rv$data <- read.csv(input$file$datapath)
rv$n <- nrow(rv$data)
})
# Expensive model only on 'Run' click
model <- eventReactive(input$run, {
lm(y ~ ., data = isolate(rv$data))
})
output$summary <- renderPrint({ summary(model()) })
}Questions Fréquemment Posées
La leçon « Approfondissement de la programmation réactive » est-elle gratuite ?
Oui — le texte complet de « Approfondissement de la programmation réactive » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Approfondissement de la programmation réactive » ?
Comprenez les valeurs réactives, les objets réactifs, les observateurs et le graphe réactif. Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer R Academy ?
Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Approfondissement de la programmation réactive » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon R Academy ?
Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Approfondissement de la programmation réactive
- Modules Shiny pour réutiliser le code
- Interface dynamique avec renderUI et insertUI
- Déployer des applications Shiny