Reputation: 1113
Hi I'm trying my hand at ClojureScript and I'm using Klipse as my REPL pretty much. It's maybe not it's intended use but because I don't do anything too complicated it's fine for now.
One problem I have is trying to setup a timer. My code is:
(ns my.reagent-examples
(:require [reagent.core :as r]))
(when-let [element (js/document.getElementById "app")]
(r/render-component [component] element))
;; State
(def app-state (r/atom 0)) ;; Initial value is 0
;; Increment seconds
(js/setInterval #(swap! app-state inc) 1000) ;; Increment app-state every 1000ms
;; "Seconds elapsed" component
(defn timer []
[:div (str "Seconds elapsed: " @app-state)])
It show a timer but it's too fast and seems to accelerate as time goes by. Intended result would be a counter incrementing every second.
My full Klipse file is like this:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css">
<script>
window.klipse_settings = {
selector: '.language-klipse', // css selector for the html elements you want to klipsify
selector_reagent: '.language-reagent', // selector for reagent snippets
};
</script>
</head>
<body>
<pre><code class="language-reagent">
(ns my.reagent-examples
(:require [reagent.core :as r]))
(when-let [element (js/document.getElementById "app")]
(r/render-component [component] element))
;; State
(def app-state (r/atom 0)) ;; Initial value is 0
;; Increment seconds
(js/setInterval #(swap! app-state inc) 1000) ;; Increment app-state every 1000ms
;; "Seconds elapsed" component
(defn timer []
[:div (str "Seconds elapsed: " @app-state)])
</code></pre>
<script src="https://storage.googleapis.com/app.klipse.tech/plugin/js/klipse_plugin.js"></script>
</body>
(Run the snippet in full page to see the timer)
EDIT: I look like a fool because in the snippet the timer look like it run normally, but when I open the exact same HTML file with Google Chrome or Firefox, the timer goes nuts.. What could be the reason for that?
EDIT2: It seems if you change things on the snippet, you'll see the timer going faster, is that because there it is rendered too many time?
Upvotes: 3
Views: 351
Reputation: 13175
The issue probably is that when you edit and save your code, it's hot-reloaded in your browser and starts another js/setInterval
without stopping the previous one.
You can fix it by calling js/setInterval
in defonce
definition that will be executed only once on first load and won't be called on reloads:
(defonce timer-increment-interval
(js/setInterval #(swap! app-state inc) 1000)) ;; Increment app-state every 1000ms
Upvotes: 2