Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save anthonybrown/4a93fc10499d5341338f7a7a2f6b2727 to your computer and use it in GitHub Desktop.
Save anthonybrown/4a93fc10499d5341338f7a7a2f6b2727 to your computer and use it in GitHub Desktop.
Simple counter: different implementations...
different implementations of the simple counter app... code verbosity vs expressiveness
m.mount(document.body, {
count : 0,
view : (vnode) => m("div",
m("div", "Count: ", vnode.state.count),
m("button", { onclick : () => vnode.state.count++ }, "+"),
m("button", { onclick : () => vnode.state.count-- }, "-")
)
})
new Vue({
data: { count: 0 },
render (h) {
return h('p', [
this.count,
h('button', { on: { click: () => { this.count++ }}}, '+'),
h('button', { on: { click: () => { this.count-- }}}, '-')
])
}
}).$mount('#app')
import Dom exposing (..)
import Lens exposing (Lens)
counter : Lens m Int -> Html m
counter value =
div []
[ button [onClick (Lens.modify value ((+) -1))] [text "-"]
, textAs toString value
, button [onClick (Lens.modify value ((+) 1))] [text "+"]
]
(def state (atom 0))
(rum/defc view < rum/reactive [state]
[:div
[:button {:on-click #(swap! state dec)} "-"]
[:span (rum/react state)]
[:button {:on-click #(swap! state inc)} "+"]])
(run/mount (view state)
(js/document.getElementById "app"))
import * as R from "ramda"
import * as U from "karet.util"
import React from "karet"
import ReactDOM from "react-dom"
const Counter = ({value}) =>
<div>
<div>Count: {value}</div>
<button onClick={() => value.modify(R.add(+1))}>+</button>
<button onClick={() => value.modify(R.add(-1))}>-</button>
</div>
ReactDOM.render(<Counter value={U.atom(0)}/>, document.getElementById("app"))
import { h, app } from "hyperapp"
app({
model: 0,
update: {
add: model => model + 1,
sub: model => model - 1
},
view: (model, actions) =>
<div>
<button onclick={actions.add}>+</button>
<h1>{model}</h1>
<button onclick={actions.sub} disabled={model <= 0}>-</button>
</div>
})
data Action = Increment | Decrement
type State = Int
update :: Action -> State -> State
update Increment count = count + 1
update Decrement count = count - 1
view :: State -> Html Action
view count =
div
[]
[ button [ onClick (const Increment) ] [ text "Increment" ]
, span [] [ text (show count) ]
, button [ onClick (const Decrement) ] [ text "Decrement" ]
]
import React from 'react'
export const init = count => count
const Action = {
Increment: x => x + 1,
Decrement: x => x - 1
}
export const update = (action, model) => action(model)
export const view = (signal, model) => (
<div>
<button onClick={signal(Action.Decrement)}>-</button>
<div>{model}</div>
<button onClick={signal(Action.Increment)}>+</button>
</div>
)
export default {init, update, view}
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import React from 'react'
import {render} from 'react-dom'
const state = { n: 0 };
const incr = () => state.n++;
const decr = () => state.n--;
const view = observer(() =>
<div>
<h1>{state.n}</h1>
<button onclick={incr}>+</button>
<button onclick={decr}>-</button>
</div>)
render(
<view />,
document.querySelector('#app')
);
import xs from 'xstream';
import Cycle from '@cycle/xstream-run';
import {div, button, p, makeDOMDriver} from '@cycle/dom';
function main(sources) {
let action$ = xs.merge(
sources.DOM.select('.decrement').events('click').map(ev => -1),
sources.DOM.select('.increment').events('click').map(ev => +1)
);
let count$ = action$.fold((x,y) => x + y, 0);
return {
DOM: count$.map(count =>
div([
button('.decrement', 'Decrement'),
button('.increment', 'Increment'),
p('Counter: ' + count)
])
)
};
}
Cycle.run(main, {
DOM: makeDOMDriver('#main-container')
});
const choo = require('../../')
const html = require('../../html')
const app = choo()
app.model({
state: {
counter: 0
},
reducers: {
increment: (data, state) => ({ counter: state.counter + 1 }),
decrement: (data, state) => ({ counter: state.counter - 1 })
}
})
const mainView = (state, prev, send) => {
return html`
<main class="app">
<button onclick=${() => send('increment')}>Increment</button>
<button onclick=${() => send('decrement')}>Decrement</button>
<p>state.counter</p>
</main>
}
app.router((route) => [
route('/', mainView)
])
document.body.appendChild(app.start())
import Html exposing (Html, button, div, text)
import Html.App as App
import Html.Events exposing (onClick)
main =
App.beginnerProgram
{ model = model
, view = view
, update = update
}
type alias Model = Int
model : Model
model = 0
type Msg = Increment | Decrement
update : Msg -> Model -> Model
update msg model =
case msg of
Increment -> model + 1
Decrement -> model - 1
view : Model -> Html Msg
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (toString model) ]
, button [ onClick Increment ] [ text "+" ]
]
import React, { Component, PropTypes } from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
class Counter extends Component {
static propTypes = {
value: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired
}
render() {
const { value, onIncrement, onDecrement } = this.props
return (
<p>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
</p>
)
}
}
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
const store = createStore(counter)
const rootEl = document.getElementById('root')
const render = () => ReactDOM.render(
<Counter
value={store.getState()}
onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
/>,
rootEl
)
render()
store.subscribe(render)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment