From 36005608913bd0e1091f7f2c745f3329692c7c3a Mon Sep 17 00:00:00 2001 From: Kimo Knowles Date: Wed, 22 Nov 2023 13:36:39 +0100 Subject: [PATCH] [docs] polish --- docs/FAQs/UseASubscriptionInAnEventHandler.md | 7 ++-- docs/Flows.md | 41 +++++++++++-------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/docs/FAQs/UseASubscriptionInAnEventHandler.md b/docs/FAQs/UseASubscriptionInAnEventHandler.md index 7b29295e5..e37ae65d1 100644 --- a/docs/FAQs/UseASubscriptionInAnEventHandler.md +++ b/docs/FAQs/UseASubscriptionInAnEventHandler.md @@ -22,10 +22,11 @@ But this comes with a caveat: **the only safe place to call `subscribe` is withi Inner functions, such as DOM event handlers, don't count. Consider this component: ```clj -[:button {:on-click #(subscribe [:some (gensym)])}] +(defn my-btn [] + [:button {:on-click #(subscribe [:some (gensym)])}]) ``` -Our `:on-click` function isn't actually called here. Instead, we've given the function to the browser, expecting it to get called later. The problem is, reagent and re-frame have no way to safely manage your subscription at that time. The result is a memory leak. If the browser calls your `:on-click` a thousand times, re-frame will "create" a thousand unique subscriptions, and there's no code in place to "dispose" them later. +Our `:on-click` function isn't actually called when the component renders. Instead, we've given the function to the browser, expecting it to get called later. The problem is, reagent and re-frame have no way to safely manage your subscription at that time. The result is a memory leak. If the browser calls your `:on-click` a thousand times, re-frame will "create" a thousand unique subscriptions, and there's no code in place to "dispose" them later. ### Re-frame event handlers @@ -41,7 +42,7 @@ Re-frame event handlers don't count either. Re-frame calls your event handlers w Furthermore, this is a conceptual issue. Your subscription handler may be pure, but `subscribe` always has a side-effect. -Calling `subscribe` inside an event handler goes against re-frame's design, which is based on handlers being pure functions. +Calling `subscribe` inside an event handler goes against re-frame's design, which is based on [handlers being pure functions](/re-frame/on-dynamics/#pure-functions). ### Incidental safety diff --git a/docs/Flows.md b/docs/Flows.md index e7c5a8cdb..72316e82f 100644 --- a/docs/Flows.md +++ b/docs/Flows.md @@ -155,23 +155,6 @@ And, we use this subscription in a view:
- -!!! Note "Our dataflow model" - Dataflow is often conceptualized as a graph. - Data flows through edges, and transforms through nodes. - Here's how our DSL articulates the traditional dataflow model: - - - `flow` - a map, serving as a node specification - - `:id` - uniquely identifies a node - - `:inputs` - a set of edges from other nodes - - `reg-flow` - creates a running node from a specification - - Crucially, the name `flow` isn't exactly short for "dataflow". - A `flow` is a static value, specifying one possible segment of a dataflow graph. - Dataflow is a [dynamic process](/re-frame/on-dynamics/#on-dynamics), not a value. - Both the data and the graph itself change over time. - Changing the graph is a matter of [registering and clearing](#redefining-and-undefining) flows. - ## How does it work? `event handlers` yield `effects`. Typically, they yield a `:db` effect, causing a new value of `app-db`. @@ -300,6 +283,30 @@ When either input changes value, our flow calls the `:output` function to recalc As before, once `:output` runs, the resulting value is stored at `:path`. So, the new value of `app-db` will contain a number at the path `[:ratios :main-rooms]` +Under the hood, flows relate to each other in a depedency graph. +An input like `(rf/flow<- ::kitchen-area)` creates a dependency. +That means re-frame will always run `::kitchen-area` first, +ensuring its output value is current before your `:main-room-ratio` flow can use it. + +!!! Note "Our dataflow model" + Dataflow is often conceptualized as a graph. + Data flows through edges, and transforms through nodes. + Here's how our DSL articulates the traditional dataflow model: + + - `flow` - a map, serving as a node specification + - `:id` - uniquely identifies a node + - `:inputs` - a set of edges from other nodes + - `flow<-` - declares another node id as an input dependency + - `reg-flow` - creates a running node from a specification + + Crucially, the name `flow` isn't exactly short for "dataflow". + A `flow` is a static value, specifying one possible segment of a dataflow graph. + Dataflow is a [dynamic process](/re-frame/on-dynamics/#on-dynamics), not a value. + Both the data and the graph itself can change over time. + + - Changing the data means running the flows which are currently registered. + - Changing the graph is a matter of [registering and clearing](#redefining-and-undefining) flows. + ## Subscribing to flows In our examples so far, we've used a regular subscription, getting our flow's output path.