Skip to content

Instantly share code, notes, and snippets.

@johnstew
Created July 13, 2017 20: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 johnstew/e5bc00ab1a03da8ce558b4c676729745 to your computer and use it in GitHub Desktop.
Save johnstew/e5bc00ab1a03da8ce558b4c676729745 to your computer and use it in GitHub Desktop.
Exploring App State
function equal(objA, objB) {
const sObjA = JSON.stringify(objA);
const sObjB = JSON.stringify(objB);
return (sObjA === sObjB);
}
class AppState {
constructor(state = {}, components = []) {
this.state = state;
this.components = components;
}
update(newState = {}) {
// merge
const nextState = Object.assign({}, this.state, newState);
console.log(`AppState Update:`, nextState);
// set
this.state = nextState;
// notify components
this.notify();
}
registerComponent(component) {
if (!component) {
throw new Error('AppState: missing required component')
return false;
}
// register state to component
component.appState = this.state;
// add component to array store
this.components.push(component);
// notify components
this.notify();
return true;
}
notify() {
this.components.forEach((c) => c.update(this.state));
}
}
class Button {
constructor(selector = null, state = { color: 'red', text: 'Login' }) {
this.state = state;
this.button = selector ? document.querySelector(selector) : document.createElement('button');
this.appState = {}; // this gets set on component registration
}
render() {
this.button.innerHTML = this.state.text;
this.button.style.backgroundColor = this.state.color;
this.button.onclick = () => (console.log(`State: `, this.state));
document.body.appendChild(this.button);
}
update(newAppState) {
if (!newAppState) {
throw new Error('Button Update: missing newAppState');
return;
}
/**
* Login Button Biz Logic
*
* Color
* =======
*
* user.loggedIn = red
* !user.loggedIn = blue
*
* Text
* =======
*
* user.loggedIn = Logout
* !user.loggedIn = Login
*/
if (equal(this.appState, newAppState)) {
console.warn('AppState is the same, no updates performed.');
return;
}
const { user: { loggedIn } } = newAppState;
this.state.color = loggedIn ? 'red' : 'blue';
this.state.text = loggedIn ? 'Logout' : 'Login';
this.render();
}
}
const state = new AppState();
const button = new Button();
state.registerComponent(button);
state.update({
user: {
loggedIn: false
}
});
// setInterval(() => {
// state.update({
// user: {
// loggedIn: !state.state.user.loggedIn
// }
// });
// }, 1000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment