@Injectable ( )
export class AppService {
value = 0 ;
incrementState = ( ) => Promise . resolve ( this . value ++ ) ;
}
@Component ( {
selector : 'body' ,
template : `
<h1>{{value}}</h1>
<button (click)="incrementState()">+1</button>
` ,
providers : [ AppService ]
} )
export class AppComponent implements OnInit {
constructor ( private appService : AppService ) { }
value = 0 ;
incrementState = ( ) => this . appService . incrementState ( )
. then ( value => this . value = value ) ;
}
bootstrap ( AppComponent ) ;
// state container
const state = { value : 0 }
// actions
const incrementState = ( dispatch , state ) =>
( ) => dispatch ( { value : state . value + 1 } ) ;
// dumb component
const Incrementer = connect ( ( props ) => < main >
< h1 > { props . value } </ h1 >
< button
onClick = { props . actions . incrementState }
>
+1
</ button >
</ main > , state , { incrementState} ) ;
/* RENDER */
ReactDOM . render ( < Incrementer /> ,
document . querySelector ( "div" ) )
ECMA2017 + React connector
const connect = ( el , state , actions ) =>
class Connect extends React . Component {
constructor ( ) {
super ( ) ;
this . state = state ;
}
render ( ) {
const { state, setState } = this ;
const dispatch = setState . bind ( this ) ;
const binderReducer = ( current , next ) =>
( { ...current ,
[ next ] : actions [ next ] ( dispatch , state ) } ) ;
const bindedActions = Object . keys ( actions )
. reduce ( binderReducer , { } ) ;
const props = { ...state , actions : bindedActions } ;
return React . cloneElement ( el ( props ) ) ;
}
}
(ns cljsfiddle.app
(:require [reagent.core :refer [atom]]])
; ; state container
(def state (atom {:value 0 }))
; ; action
(defn increment-state [state]
(fn [_]
(swap! state update-in [:value ] inc)))
; ; dumb component
(defn incrementer [] [:main
[:h1 (:value @state)]
[:button
{:on-click (increment-state state)}
" +1" ]])
; ; render
[incrementer]
CLJS fiddle