Skip to content

Instantly share code, notes, and snippets.

@pirate
Created February 26, 2020 22:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pirate/4755b93402a2d06e53d5ba5f2fab1b76 to your computer and use it in GitHub Desktop.
Save pirate/4755b93402a2d06e53d5ba5f2fab1b76 to your computer and use it in GitHub Desktop.
A demo of redux coded by hand with React
<html>
<div id="root"></div>
<script>
const initial_state = {
playbar: {
playing: true,
position: 40.6345,
currentTrack: 2342355,
currentPlaylist: 124234,
}
}
// const sendWebsocketMessages = (oldstate, newstate, store) => {
// // newstate = {to_send: [{user: 'nick', playstate: 'playing'}]}
// for (const message of newstate.to_send) {
// // perform the side effect
// websocket.send(message)
// // can we do this here? change state via dispatch from a subscriber?
// store.dispatch({type: 'MARK_WEBSOCKET_MESSAGE_SEND', message})
// // no, it's bad idea, use:
// // - redux-thunk
// // - redux-sagas
// }
// }
// const store = createStore({to_send: []}, reducers, [sendWebsocketMessages])
const store = {
state: initial_state,
onNewStateCallbacks: [],
subscribe: (onNewState) => {
this.onNewStateCallbacks.push(onNewState)
}
setState: (newstate) => {
const oldstate = this.state
this.state = newstate
for (const callback of this.onNewStateCallbacks) {
callback(oldstate, newstate, this)
}
},
dispatch: (action) => {
this.setState(this.reducer(this.state, action))
},
reducer: (state, action) => {
switch (action.type) {
case 'PLAY':
return {
...state,
playbar: {
...state.playbar,
playing: true,
}
}
case 'PAUSE':
return {
...state,
playbar: {
...state.playbar,
playing: false,
}
}
case 'SET_PLAYSTATE':
return {
...state,
playbar: {
...state.playbar,
playing: action.playing,
}
}
default:
return state
}
}
}
const PlayBar = ({store}) =>
<div>
<button onClick={(event) => {store.dispatch({type: 'SET_PLAYSTATE', playing: !store.state.playbar.playing})}}>
{store.state.playbar.playing ? "Pause" : "Play"}
</button>
<input type="slider" position={store.state.playbar.position}/>
<a href={`/playlists/${store.state.playbar.currentPlaylist}`}>
Go to playlist
</a>
</div>
const render = (store) => {
store.subscribe(render)
ReactDOM.render(
document.getElementById('root'),
<PlayBar state={store.state} dispatch={dispatch}/>
)
}
// render()
// ...
// eventloop queue:
// #root onClick => (event) => {store.dispatch({type:...})}
// 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// ^ click,render
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment