omcljs / om

ClojureScript interface to Facebook's React
6.66k stars 362 forks source link

[om.next] Make example of a reusable Counter component #867

Open vitalije opened 7 years ago

vitalije commented 7 years ago

Create example code that shows how to make reusable component.

Let us imagine that we have a component Counter that when rendered with the state like {:count 34} gives something like the following html code:

<div class="counter">
     <p>Count: 34</p>
     <button>Click me</button>
 </div>

Every time user clicks the button in Counter component, displayed number as well as the value corresponding to the key :count in Counter's state get increased by 1.

Now let us assume that we have global app-state defined like:

    {:count 12
     :a { :count 14}
     :b { :c { :count 17}}
     :c { :d [
                {:count 18}
                {:count 19}]
        }
    }

Provide an example how should be implemented render method of app-root component that will have 5 children of type Counter which are bound to the 5 different paths inside app-state (each ending in {:count <value>}).

Is it possible for the author of Counter component to define it in such a way that it can be easily instantiated providing just some kind of a path from root state to the {:count ...} value? Can the author of Counter component provide read :counter/value and mutate :counter/value functions?

noonian commented 7 years ago

Hello, I wrote a small counter example here: https://github.com/noonian/om-next-counters-example

The counter's know how to update themselves by using idents so each counter's state must have an id.

I recently updated the UI to be somewhat generic by allowing the parent component to pass itself as the target to transact! so that it will be re-rendered when the counter updates. I'd welcome any feedback on this approach (the counters previously referenced the parent's :sorted/counters key in their transactions to force a re-render of the parent).

I believe one could expose the read and mutate functions on their own and allow the parent application to explicitly compose them in the parser but I'll leave that as an exercise for the reader ;)