/reagent-cursor

Optional cursors library for Reagent

Primary LanguageClojureEclipse Public License 1.0EPL-1.0

Deprecated

As part of the migration to the new reagent-project organization, an earlier version of this cursors library was folded into Reagent's core. As part of the Reagent 0.5.0 release, that implementation of cursors has been substantially enhanced (both in performance and in generalization) so this standalone cursor library should be considered deprecated.

Note that the argument order in Reagent core is different - atom first, path second - so switching from this library to Reagent core will involve code changes but they are straightforward.

Cursors

Cursors can be seen as a kind of pointer to a particular part of an atom, which behaves exactly like a normal atom. This means that you use the same functions you would on an atom (reset!, swap!, deref, add-watch, etc) but affect only the part you are interested in.

This enables you to create reusable functions and components by abstracting away complex paths and getter/setter functions.

;; what was...
(swap! my-atom update-in [:some :path :that :might :be :quite :deep] my-fn)

;; ...can now become

(swap! my-cursor my-fn)

;; Notice that the path is no longer hardcoded; it could be a simple
;; atom, or a cursor pointing to the 10th level of a complex nested
;; hashmap.

;; How about associating a value into the nested structure? No
;; problem! Just `reset!` the cursor:

(reset! my-cursor "my-new-value")

;; Now just deref it:

@my-cursor

=> "my-new-value"

Usage

Add [reagent/reagent-cursor "0.1.2"] to :dependencies in project.clj.

In your Reagent application (:require [reagent.cursor :as rc]).

There are two main functions available to create cursors: cursor and cur.

cursor

cursor has two arities.

When given a single argument (a path), it returns a function that can create a cursor when given an atom. Useful to create mutliple cursors with the same path.

(def my-custom-cursor-fn (rc/cursor [:some :arbitrary :path]))

(map my-custom-cursor-fn [atom1 atom2 atom3])

;; this will return a collection of [cursor1 cursor2 cursor3]

When given two arguments, cursor will return a cursor.

(def c1 (rc/cursor [:some :arbitrary :path] atom1))

cur

cur is the little brother of cursor. It will only accept 2 arguments (the atom and a path), but is guaranteed to return a cursor.

Note that the atom argument is placed on the left, allowing you to use a thread-first macro (cursor requires a thread-last macro).

(-> my-atom
	(rc/cur [:some :path]) ;; <---- create the cursor
	(add-watch :my-watch #(println "updated!"))
	(historian/record! :my-state)
    (ls/local-storage :my-state))
	

License

Copyright (c) 2014 Sean Corfield

Distributed under the Eclipse Public License, the same as Clojure.