Last active
May 15, 2018 16:17
-
-
Save wordyallen/fbd9e239656cb6232fc3bfbcfb987522 to your computer and use it in GitHub Desktop.
Learning MobX
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react' | |
import { observable } from 'mobx' | |
import { observer } from 'mobx-react' | |
@observer | |
class Counter extends Component{ | |
@observable count = 0 | |
render (){ | |
return( | |
<div > | |
Counter: {this.count} <br/> | |
<button onClick={this.handleDec}>-</button> | |
<button onClick={this.handleInc}>+</button> | |
</div> | |
) | |
} | |
handleDec = () => this.count-- | |
handleInc = ()=> this.count++ | |
} | |
export default <Counter/> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react' | |
import {observer} from 'mobx-react' | |
import {Provider, inject} from 'mobx-react' | |
const TimerDisplay = ({timer,text})=>( | |
<div style={display.displayContainer}> | |
<div style={display.time}>{text}</div> | |
<div style={display.lap}>{timer.display}</div> | |
</div> | |
) | |
const RunningButtons = inject('store')(observer(({store})=>( | |
<div> | |
<button style={{...button, color: '#fd3d2a'}} onClick={() => store.stopTimer()}> | |
stop | |
</button> | |
<button style={button} onClick={() => store.lapTimer()}> | |
lap | |
</button> | |
</div> | |
))) | |
const StartButtons = inject('store')(observer(({store})=>( | |
<div> | |
<button style={{...button, color: '#4bd761'}} onClick={() => store.startTimer()}> | |
start | |
</button> | |
<button style={button} onClick={() => store.resetTimer()}> | |
reset | |
</button> | |
</div> | |
))) | |
export default observer( ({store})=>{ | |
const {mainDisplay, isRunning, lapData} = store | |
return ( | |
<Provider store={store}> | |
<div> | |
<div style={main}> | |
{mainDisplay} | |
</div> | |
<div> | |
<div style={bContainer}> | |
{isRunning ? <RunningButtons />:<StartButtons />} | |
</div> | |
<div> | |
{lapData.map( ({timer, text},i) => <TimerDisplay key={i} timer={timer} text={text}/>)} | |
</div> | |
</div> | |
</div> | |
</Provider> | |
) | |
}) | |
const display ={ | |
displayContainer:{ | |
display: 'flex', | |
borderBottom: '1px solid #d9dae0', | |
fontSize: 30 | |
}, | |
time :{ | |
fontSize: 30, | |
fontFamily: 'HelveticaNeue-UltraLight', | |
color: '#7f8083', | |
padding: 20, | |
flex: 1 | |
}, | |
lap:{ | |
padding: 20, | |
fontFamily: 'HelveticaNeue-UltraLight', | |
color: '#7f8083', | |
} | |
} | |
const button ={ | |
fontFamily: 'HelveticaNeue-UltraLight', | |
fontSize: 20, | |
width: 72, | |
height: 72, | |
margin: 24, | |
padding: 0, | |
cursor: 'pointer', | |
letterSpacing: 1, | |
border: 0, | |
borderRadius: '50%', | |
outline: 'none', | |
background: 'white', | |
} | |
const main = { | |
background: 'white', | |
height: 120, | |
fontSize: 60, | |
fontFamily: 'HelveticaNeue-UltraLight', | |
border: 'solid #cecfd0', | |
display: 'flex', | |
alignItems: 'center', | |
justifyContent: 'center' | |
} | |
const bContainer={ | |
display: 'flex', | |
alignItems: 'center', | |
justifyContent: 'center' | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const moment = require('moment'), | |
{observable, computed, action, runInAction} = require('mobx'), | |
format = require('format-number-with-string') | |
class Timer{ | |
@observable milliseconds = 0 | |
@observable savedMilliseconds =0 | |
constructor(initialMilliseconds=0){ | |
runInAction('Set observed state values', | |
()=> this.milliseconds= initialMilliseconds) | |
} | |
@computed get totalMilliSeconds(){ | |
return this.milliseconds + this.savedMilliseconds | |
} | |
@computed get display(){ | |
const tenMilliSeconds = parseInt(this.totalMilliSeconds/10, 10) | |
const seconds = parseInt(tenMilliSeconds/100, 0) | |
const minutes = parseInt(seconds / 60, 10) | |
return `${minutes} : ${format(seconds % 60, '00')} : ${format(tenMilliSeconds % 100, '00')}`; | |
} | |
@action saveTime(){ | |
this.savedMilliseconds += this.milliseconds | |
this.milliseconds=0 | |
} | |
@action reset(){ | |
return this.savedMilliseconds = 0 | |
} | |
} | |
export default class { | |
@observable isRunning = false | |
@observable timer = new Timer() | |
@observable startTime | |
@observable laps =[] | |
@computed get mainDisplay(){ | |
return this.timer.display | |
} | |
@computed get lapTime() { | |
return this.laps.map( timer => timer.totalMilliSeconds) | |
.reduce((x, y) => x + y, 0); | |
} | |
// I dont understand this.... | |
@action lapTimer() { | |
this.laps.push(new Timer(this.timer.totalMilliSeconds - this.lapTime)); | |
} | |
@computed get lapData() { | |
return this.laps | |
.map( (timer, i) =>({timer, text: `Lap ${i + 1}`})).reverse() | |
} | |
@action stopTimer(){ | |
this.timer.saveTime() | |
this.isRunning = false | |
} | |
@action measure(){ | |
if (!this.isRunning) return; | |
this.timer.milliseconds = moment().diff(this.startTime); | |
setTimeout(() => this.measure(), 10); | |
} | |
@action startTimer(){ | |
if (this.isRunning) return; | |
this.isRunning = true; | |
this.startTime = moment(); | |
this.measure(); | |
} | |
@action resetTimer(){ | |
this.timer.reset() | |
this.laps = [] | |
this.isRunning=false | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react' | |
import { render } from 'react-dom' | |
import { AppContainer } from 'react-hot-loader' | |
import { observable, computed, action } from 'mobx' | |
import { observer } from 'mobx-react' | |
import DevTools from 'mobx-react-devtools' | |
class Temperature { | |
id = Math.random() | |
@observable unit = "C" | |
@observable tempCelsius = 25 | |
@computed get tempKelvin(){ | |
console.log(`comping K`) | |
return this.tempCelsius + 273.15 | |
} | |
@computed get tempFahrenheit(){ | |
console.log(`comping F`) | |
return this.tempCelsius*(9/5)+32 | |
} | |
@computed get temperature(){ | |
console.log('comping temp') | |
switch(this.unit){ | |
case "K": return `${this.tempKelvin} °K` | |
case "C": return `${this.tempCelsius} °C` | |
case "F": return `${this.tempFahrenheit} °F` | |
} | |
} | |
@action setUnit(newUnit){ | |
this.unit = newUnit | |
} | |
@action setCelsius(deg){ | |
this.tempCelsius = deg | |
} | |
@action('update temp and unit') | |
setTempandUnit(deg, unit){ | |
this.setCelsius(deg) | |
this.setUnit(unit) | |
} | |
} | |
const temps = observable([]) | |
temps.push(new Temperature()) | |
const App = observer( | |
({temperatures}) => ( | |
<div> | |
{temperatures.map( (t,i)=><div key={i}>{t.temperature}</div> )} | |
<br/> | |
</div> | |
) | |
) | |
render( | |
<AppContainer> | |
<App temperatures={temps} /> | |
</AppContainer>, | |
document.getElementById('root') | |
); | |
if (module.hot) { | |
module.hot.accept('./App', () => { | |
const NextApp = require('./App').default; | |
render( | |
<AppContainer> | |
<NextApp temps={temps} /> | |
</AppContainer>, | |
document.getElementById('root') | |
); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment