diff --git a/src/reagent/core.cljs b/src/reagent/core.cljs index c858101..a00db6b 100644 --- a/src/reagent/core.cljs +++ b/src/reagent/core.cljs @@ -160,6 +160,16 @@ Equivalent to (swap! (state-atom this) merge new-state)" (assert (or (nil? new-state) (map? new-state))) (swap! (state-atom this) merge new-state)) +(defn force-update + "Force a component to re-render immediately. + + If the second argument is true, child components will also be + re-rendered, even is their arguments have not changed." + ([this] + (force-update this false)) + ([this deep] + (util/force-update this deep))) + (defn props "Returns the props passed to a component." diff --git a/src/reagent/impl/util.cljs b/src/reagent/impl/util.cljs index ce62a24..c63ac10 100644 --- a/src/reagent/impl/util.cljs +++ b/src/reagent/impl/util.cljs @@ -137,3 +137,9 @@ (doseq [v (vals @roots)] (apply re-render-component v)) "Updated") + +(defn force-update [comp deep] + (if deep + (binding [*always-update* true] + (.' comp forceUpdate)) + (.' comp forceUpdate))) diff --git a/test/reagenttest/testreagent.cljs b/test/reagenttest/testreagent.cljs index 6f60bf2..ec81bae 100644 --- a/test/reagenttest/testreagent.cljs +++ b/test/reagenttest/testreagent.cljs @@ -516,3 +516,27 @@ (rstr [:div.foo [:p.bar.foo [:b.foobar "xy"]]]))) (is (= (rstr [:div>p.bar.foo>a.foobar {:href "href"} "xy"]) (rstr [:div [:p.bar.foo [:a.foobar {:href "href"} "xy"]]])))) + +(deftest test-force-update + (let [v (atom {:v1 0 + :v2 0}) + comps (atom {}) + c1 (fn [] + (swap! comps assoc :c1 (r/current-component)) + [:p (swap! v update-in [:v1] inc)]) + c2 (fn [] + (swap! comps assoc :c2 (r/current-component)) + [:p (swap! v update-in [:v2] inc) + [c1]])] + (with-mounted-component [c2] + (fn [c div] + (is (= @v {:v1 1 :v2 1})) + + (r/force-update (:c2 @comps)) + (is (= @v {:v1 1 :v2 2})) + + (r/force-update (:c1 @comps)) + (is (= @v {:v1 2 :v2 2})) + + (r/force-update (:c2 @comps) true) + (is (= @v {:v1 3 :v2 3}))))))