JSFiddle - React, Tailwind, and code Playground
HTML
<div class="container">
<div class="alert alert-info">
<Button id="toggle">toggle</Button>
State: <span id="result"></span>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.min.js"></script>
CSS
body {
font-family: sans-serif;
padding: 10px;
}
h2 {
font-weight: bold;
display: inline-block;
margin-left: 20px;
}
.header {
background: #ECECEC;
padding: 5px;
}
JavaScript
var toggleEl = document.querySelector('#toggle');
var resultEl = document.querySelector('#result');
// in real life, the init stream comes from an async source
const init$ = Rx.Observable.from([true]);
const toggleInit$ = init$
.map( e => {
return { 'what': 'initialize', 'value': e};
})
const toggle$ = Rx.Observable.fromEvent(toggleEl, 'click')
.map( e => {
return { 'what': 'toggle'};
});
const toggle = toggle$.merge(toggleInit$)
.scan( (acc, v) => {
if(v.what == 'toggle') {
acc.state = !acc.state;
} else if(v.what == 'initialize') {
if(acc.isRunning == false) {
acc.state = v.value;
}
}
if(acc.isRunning == false)
acc.isRunning = true;
return acc;
}, { 'isRunning': false, 'state': true}) // state contains default value
.map( acc => acc.state)
.subscribe( (v) => {
resultEl.innerHTML = v;
});