Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Nov 21, 2023
1 parent a631473 commit 06f1a37
Show file tree
Hide file tree
Showing 6 changed files with 1,211 additions and 1,206 deletions.
12 changes: 8 additions & 4 deletions FAQs/UseASubscriptionInAnEventHandler/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1707,7 +1707,7 @@ <h3 id="re-frame-event-handlers">Re-frame event handlers<a class="headerlink" hr
Calling <code>subscribe</code> inside an event handler goes against re-frame's design, which is based on handlers being pure functions.</p>
<h3 id="incidental-safety">Incidental safety<a class="headerlink" href="#incidental-safety" title="Permanent link">&para;</a></h3>
<p>Calling <code>subscribe</code> <em>outside</em> a component is somewhat safe, as long as you've also called it <em>inside</em> a component.
The <em>outside</em> one has no way to dispose, but the <em>inside</em> one might dispose it later.</p>
The <em>outside</em> one has no way to dispose, but the <em>inside</em> one might dispose later.</p>
<p>Of course, that requires your component to be around while your other code runs.
If that component unmounts and never comes back, then you're on your own again.</p>
<p>This isn't a real solution, it's just incidental safety.</p>
Expand All @@ -1717,7 +1717,8 @@ <h3 id="restructure-your-app">Restructure your app<a class="headerlink" href="#r
<h4><em>Don't</em> call <code>subscribe</code> in your event handler:</h4>
<div class="codehilite"><pre><span></span><code><span class="p">(</span><span class="nf">reg-sub</span> <span class="ss">:areas</span> <span class="p">(</span><span class="k">fn </span><span class="p">[</span><span class="nv">db</span><span class="p">]</span> <span class="p">(</span><span class="nb">map </span><span class="p">(</span><span class="k">fn </span><span class="p">[</span><span class="nv">r</span><span class="p">]</span> <span class="p">(</span><span class="nb">* </span><span class="nv">Math/PI</span> <span class="nv">r</span> <span class="nv">r</span><span class="p">))</span> <span class="p">(</span><span class="ss">:circles</span> <span class="nv">db</span><span class="p">))))</span>

<span class="p">(</span><span class="nf">reg-event-fx</span> <span class="nv">store-areas</span>
<span class="p">(</span><span class="nf">reg-event-fx</span>
<span class="ss">:store-areas</span>
<span class="p">(</span><span class="k">fn </span><span class="p">[{</span><span class="ss">:keys</span> <span class="p">[</span><span class="nv">db</span><span class="p">]}</span> <span class="nv">_</span><span class="p">]</span>
<span class="p">{</span><span class="ss">:local-store</span> <span class="o">@</span><span class="p">(</span><span class="nf">subscribe</span> <span class="p">[</span><span class="ss">:areas</span><span class="p">])}))</span>
</code></pre></div>
Expand All @@ -1730,7 +1731,8 @@ <h4><em>Do</em> factor out calculation helpers:</h4>

<span class="p">(</span><span class="nf">reg-sub</span> <span class="nv">areas</span> <span class="p">(</span><span class="k">fn </span><span class="p">[</span><span class="nv">db</span> <span class="nv">_</span><span class="p">]</span> <span class="p">(</span><span class="nf">get-areas</span> <span class="nv">db</span><span class="p">)))</span>

<span class="p">(</span><span class="nf">reg-event-fx</span> <span class="nv">store-areas</span>
<span class="p">(</span><span class="nf">reg-event-fx</span>
<span class="ss">:store-areas</span>
<span class="p">(</span><span class="k">fn </span><span class="p">[{</span><span class="ss">:keys</span> <span class="p">[</span><span class="nv">db</span><span class="p">]}</span> <span class="nv">_</span><span class="p">]</span>
<span class="p">{</span><span class="ss">:local-store</span> <span class="p">(</span><span class="nf">get-areas</span> <span class="nv">db</span><span class="p">)}))</span>
</code></pre></div>
Expand All @@ -1744,7 +1746,9 @@ <h4><em>Don't</em> call <code>subscribe</code> in a callback:</h4>


<h4><em>Do</em> <code>dispatch</code> an event in a callback:</h4>
<div class="codehilite"><pre><span></span><code><span class="p">(</span><span class="nf">re-frame.core/reg-event-fx</span>
<div class="codehilite"><pre><span></span><code><span class="p">(</span><span class="nf">rf/reg-fx</span> <span class="ss">:circle-effect</span> <span class="nv">circle-effect!</span><span class="p">)</span>

<span class="p">(</span><span class="nf">re-frame.core/reg-event-fx</span>
<span class="ss">:clicked-button</span>
<span class="p">(</span><span class="k">fn </span><span class="p">[{{</span><span class="ss">:keys</span> <span class="p">[</span><span class="nv">circles</span><span class="p">]}</span> <span class="ss">:db</span> <span class="ss">:as</span> <span class="nv">coeffects</span><span class="p">}</span> <span class="nv">event-v</span><span class="p">]</span>
<span class="p">{</span><span class="ss">:circle-effect</span> <span class="nv">circles</span><span class="p">}))</span>
Expand Down
13 changes: 7 additions & 6 deletions flows-advanced-topics/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1630,25 +1630,26 @@ <h1>Flows - advanced topics</h1>
and memory leaks... oh my!</p>
<h3 id="reactive-context">Reactive context<a class="headerlink" href="#reactive-context" title="Permanent link">&para;</a></h3>
<p>To know if a thing has changed, you have to remember what it was.
To propagate change from one value to the next, you have to remember the relationship between them (a <a href="https://clojuredocs.org/clojure.core/add-watch"><code>watchable</code></a>).
Remembering is a side-effect.</p>
To propagate change from one value to the next, you have to remember their relationship (a <a href="https://clojuredocs.org/clojure.core/add-watch"><code>watchable</code></a>).
Memory is state. Remembering is a side-effect.</p>
<p>Reagent does this. Its main constructs - <em>reactive atom</em>, and <em>component</em> - are stateful, impure.
We depend on this memory. It abstracts the essential complexity of reactive programming.</p>
<p>Reagent manages atoms and components with an event loop. Only in the context of this loop can be sure reagent's memory is consistent.
<p>Reagent manages atoms and components with an event loop. Only in the context of this loop can we be sure reagent's memory is consistent.
Literally, this is called <a href="https://github.com/reagent-project/reagent/blob/a14faba55e373000f8f93edfcfce0d1222f7e71a/src/reagent/ratom.cljs#L12"><code>*ratom-context*</code></a>.</p>
<p>Generally, <code>*ratom-context*</code> only has value during the evaluation of a component function (i.e., at "render time").
<p>Generally, <code>*ratom-context*</code> only has value during the evaluation of a component function (i.e., at "render time").
When <code>*ratom-context*</code> has no value, reactive atoms behave differently.</p>
<p>You can simply call <a href="http://reagent-project.github.io/docs/master/reagent.ratom.html#var-reactive.3F"><code>reagent.ratom/reactive?</code></a>
to find out whether your code is running in a reactive context.</p>
<h4>Reactive context in re-frame</h4>
<p>Now, here's where re-frame enters the picture:</p>
<ul>
<li>An <strong>event handler</strong> is a pure function, with no reactive context (it has an <a href="/re-frame/Interceptors">interceptor</a> context).</li>
<li>A <strong>subscription handler</strong> is pure, too.</li>
<li>A <strong>subscription</strong>, on the other hand, is a reactive atom (with <em>no</em> interceptor context).</li>
<li>Calling <code>subscribe</code> has the side-effect of <em>creating</em> a <strong>subscription</strong>.</li>
</ul>
<p>Outside of a component function, a subscription's behavior differs:
Not only the behavior of the reactive atom, but also the behavior of re-frame's subscription <a href="#caching">caching</a> mechanism.</p>
<p>Outside of a reactive context, a subscription's behavior differs:
Not only the behavior of the reactive atom, but also the behavior of its <a href="#caching">caching</a> mechanism.</p>
<h4>What this means for your app</h4>
<p>Subscriptions and event handlers differ in purity and runtime context.
This means they have a <a href="https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/">coloring problem</a>.</p>
Expand Down
Loading

0 comments on commit 06f1a37

Please sign in to comment.