DEV Community

Cover image for CREATE A LIBRARY WITH JSX & CUSTOM STATE

CREATE A LIBRARY WITH JSX & CUSTOM STATE

Rahul Sharma on November 28, 2023

The core of any JavaScript framework is the state, which plays a vital role in web application development. The state determines what to render on ...
Collapse
 
hanss profile image
Hans Schenker

I want to use Rxjs in your jsx-template-with-state:

  • timer and setTimer set in useState
  • interval(1000).subscribe(v => setTimer(v))

it works but I have to run (when useEffect has no function it does not work):
useEffect( () => console.log(timer())
why is this (not working when useEffect not runs a function)

Otherwise: Congratulations for your clever idea!
hans.schenker@windowslive.com

Collapse
 
hanss profile image
Hans Schenker

useState in Typescript:

const appendChild = (parent: HTMLElement, child: string | HTMLElement, j = 0) => {
if (Array.isArray(child)) {
child.forEach((nestedChild, i) => appendChild(parent, nestedChild, i));
} else {
if (!parent.childNodes[j]) {
parent.appendChild(
child.nodeType ? child : document.createTextNode(child)
);
} else if (child !== parent.childNodes[j].data) {
parent.childNodes[j].data = child;
}
}
};

export const jsx = (tag: string | Function, props: any) => {
const { children } = props;
if (typeof tag === 'function') return tag(props);
const element = document.createElement(tag);
Object.entries(props || {}).forEach(([name, value]) => {
if (name.startsWith('on') && name.toLowerCase() in window)
element.addEventListener(name.toLowerCase().substr(2), value);
else element.setAttribute(name, value);
});

useEffect(() => {
const list = Array.isArray(children) ? children : [children];
const res = list.map((child) => {
const value = typeof child === 'function' ? child() : child;
return value;
});
appendChild(element, res);
});

return element;
};

export const jsxs = jsx;


useEffect in Typescript:

import { useState, useEffect } from "./state";

const appendChild = (parent: HTMLElement, child: string | HTMLElement, j = 0) => {
if (Array.isArray(child)) {
child.forEach((nestedChild, i) => appendChild(parent, nestedChild, i));
} else {
if (!parent.childNodes[j]) {
parent.appendChild(
child.nodeType ? child : document.createTextNode(child)
);
} else if (child !== parent.childNodes[j].data) {
parent.childNodes[j].data = child;
}
}
};

export const jsx = (tag: string | Function, props: any) => {
const { children } = props;
if (typeof tag === 'function') return tag(props);
const element = document.createElement(tag);
Object.entries(props || {}).forEach(([name, value]) => {
if (name.startsWith('on') && name.toLowerCase() in window)
element.addEventListener(name.toLowerCase().substr(2), value);
else element.setAttribute(name, value);
});

useEffect(() => {
const list = Array.isArray(children) ? children : [children];
const res = list.map((child) => {
const value = typeof child === 'function' ? child() : child;
return value;
});
appendChild(element, res);
});

return element;
};

export const jsxs = jsx;