DEV Community

Discussion on: 2021 JavaScript framework

Collapse
 
ryansolid profile image
Ryan Carniato

Yeah the counter with the c => c + 1 was just a style choice. Something React developers would find more familiar. It has the benefit of self referencing without creating a subscription (automatically untracks).

I've written a bit about the JSX transform: javascript.plainenglish.io/designi...
But often I suggest just looking at the Output tab from the REPL: playground.solidjs.com/.
While there is some optimization around grouping effects, event delegation, JavaScript ternary and boolean expression, and detection of static only expressions that don't need to be wrapped you can view the whole process basically like:

const d = <div onClick={increment}>{count()}</div>

// roughly compiles to:
const d = document.createElement("div");
d.addEventListener("click", increment);
createEffect(() => d.textContent = count());
Enter fullscreen mode Exit fullscreen mode

Mentally it creates real DOM elements and wraps expressions in Reactions(createEffect is like MobX autorun) to update the DOM. I like to think of it as roughly what I'd write if I wasn't using a template language. If you were to take the reactive system of your choice and try to create that element without tagged template literals what would you do?

This differs from something like Svelte which compiles your code into its internal component structure and distributes your code in class lifecycles. Solid system is just reactivity. The one arguable exception is the insert but it's written the way it is to avoid certain closures.. It really is:

function insert(el, fn) {
   createEffect(() => internalInsert(el, fn));
}
Enter fullscreen mode Exit fullscreen mode

The internalInsert is basically the closest equivalent to the HyperScript function except it is only concerned with insertion. What's cool about this approach is that outside spreads which (basically use the other part the HyperScript function) we know which attributes can change and just inline the effects in the compiled output. All little details but it both streamlines for performance and has this really nice benefit is most of end user code is included in a way that is easily traceable right in the compiled output.

In the end I just think of Components like factory functions where each dynamic expression closes over the state and then returns the native DOM element. This is basically the same as the HyperScript version except we shortcut all the checking of which attribute has changed.

Hopefully that makes sense.