     (if (nil? reaction)
       (set! reaction
             (if (satisfies? IDeref ratom)
-              (make-reaction #(get-in @ratom path) :on-set setter)
-              (make-reaction #(ratom path) :on-set setter)))
+              (make-reaction #(get-in @ratom path))
+              (make-reaction #(ratom path))))
       reaction))
 
   (_peek [this]
     (binding [*ratom-context* nil]
-      (-deref (._reaction this))))
+      (-deref this)))
+
+  (_set-state [this oldstate newstate]
+    (when-not (identical? oldstate newstate)
+      (set! state newstate)
+      (when (some? watches)
+        (-notify-watches this oldstate newstate))))
 
   IDeref
   (-deref [this]
-    (-deref (._reaction this)))
+    (let [oldstate state
+          newstate (-deref (._reaction this))]
+      (._set-state this oldstate newstate)
+      newstate))
 
   IReset
   (-reset! [this new-value]
-    (-reset! (._reaction this) new-value))
+    (let [oldstate state]
+      (._set-state this oldstate new-value)
+      (setter path new-value)
+      new-value))
 
   ISwap
   (-swap! [a f]

              #(reset! src %2)
              #(swap! src assoc-in path %2))
            #(src path %2))]
    (RCursor. src path s nil)))





  IWatchable
  (-notify-watches [this oldval newval]
    (doseq [[key f] watches]
      (f key this oldval newval)))
  (-add-watch [this key f]
    (set! watches (assoc watches key f)))
  (-remove-watch [this key]
    (set! watches (dissoc watches key)))

  IHash
  (-hash [this] (hash [ratom path])))
