Skip to content

Instantly share code, notes, and snippets.

@Danetag
Created April 8, 2019 15:04
Show Gist options
  • Save Danetag/593748835a954a55db667937626913c2 to your computer and use it in GitHub Desktop.
Save Danetag/593748835a954a55db667937626913c2 to your computer and use it in GitHub Desktop.
Testing a pattern getting rid of `Class`, `new`, `this` and `null`
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