Created
April 8, 2019 15:04
-
-
Save Danetag/593748835a954a55db667937626913c2 to your computer and use it in GitHub Desktop.
Testing a pattern getting rid of `Class`, `new`, `this` and `null`
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 Component = () => { | |
const states = { | |
isInit: false, | |
}; | |
const setState = (partialState = {}, callback) => { | |
if ( | |
typeof partialState !== "object" && | |
typeof partialState !== "function" && | |
partialState !== null | |
) { | |
console.error( | |
"setState(...): takes an object of state variables to update or a " + | |
"function which returns an object of state variables." | |
); | |
return; | |
} | |
for (const key in partialState) { | |
// eslint-disable-line guard-for-in | |
states[key] = partialState[key]; | |
} | |
if (callback) callback(); | |
} | |
const init = async () => new Promise(async (resolve, reject) => { | |
const { isInit } = states; | |
if (isInit) { | |
reject(); | |
return; | |
} | |
setState({isInit: true}); | |
console.log('init!'); | |
resolve(); | |
}); | |
return Object.freeze({ | |
states, | |
setState, init | |
}) | |
} | |
const DOMComponent = (props = {}) => { | |
let { selector, el, template, data } = props; | |
const component = Component(); | |
// Define more states | |
component.setState({ isDOMComponent: true }); | |
const init = async () => new Promise(async (resolve, reject) => { | |
initComponent(); | |
await component.init(); | |
resolve(); | |
}) | |
const initComponent = () => { | |
setElement(); | |
console.log('DOMComponent: initComponent', el); | |
} | |
const setState = (partialState, callback) => { | |
component.setState(partialState, callback); | |
render(); | |
} | |
const setElement = () => { | |
if (el) { | |
return; | |
} | |
if (!el && !selector && !template) { | |
console.error('You must provide a template or an el or a selector to scope a component. Creating an empty div instead'); // @preserve eslint-disable-line no-console | |
el = document.createElement('div'); | |
return; | |
} | |
if (selector) { | |
const elTemp = document.querySelector(selector) | |
if (elTemp) { | |
el = elTemp; | |
return; | |
} | |
} | |
if (template) { | |
renderTemplate(); | |
return; | |
} | |
} | |
const getElement = () => el; | |
const htmlToElement = (html) => { | |
const templateEl = document.createElement('template'); | |
html = html.trim(); // Never return a text node of whitespace as the result | |
templateEl.innerHTML = html; | |
return templateEl.content.firstChild; | |
} | |
const renderTemplate = () => { | |
const html = template.render({ data: data}); | |
el = htmlToElement(html); | |
} | |
const render = () => { | |
console.log('render'); | |
} | |
return Object.freeze({ | |
...component, setState, init, render, getElement | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment