React.js

ShockScript incorporates XML capabilities, and XML expressions allow for implementations to produce anything desired, similiar to JSX. There are certain differences to JSX or React.js.

The following demonstrates a basic XML expression for Jetâ„¢:

<j:HGroup>
    <j:Button click&={trace("clicked!")}>button 1</j:Button>
</j:HGroup>

Event handlers

In ShockScript, event handlers are expressed as e&={statementList} (note the ampersand &) as a shorthand to e={function(event){statementList}}. Furthermore, event handlers are conventionally expressed without an on prefix (for instance, click instead of onClick), and they are documented with the @eventparam tag.

Prefixes

ShockScript allows for <q:N>, whose name resolution equals q::N. Dots may be used for entities other than namespaces, as in:

<com.business.components.AppBar/>

For brevity, you do either:

import bc = com.business.components.**;

<bc:AppBar/>

or:

import com.business.components.*

<AppBar/>

Interpolation

Interpolation works similiarly to React.js, except for HTML.

<j:VGroup>
    {undefined}
    {null}
    {node}
    {nodeList}
    {plainText}
    {number}
</j:VGroup>

Interpolating attributes uses { object } and not { ...object } and must appear at most once at the end of all attributes:

<j:Button {params}>click me</j:Button>

States

Unlike React.js, in Jet+Spot there is no risk of accessing an outdated state's value, due to how states are constructed.

package com.business.components {
    //
    public function HelloWorld() {
        [State]
        var x:decimal = 0;

        return (
            <j:VGroup>
                <j:Label>clicked {x} times</j:Label>
                <j:Button click&={x++}>click me</j:Button>
            </j:VGroup>
        );
    }
}

The state's initializer represents the state's initial value.

Like React.js, there is no transitive detection of mutation methods; therefore, the following is necessary over an array .push(v):

x = [...x, v];

As to Map objects:

m = { ...m, k: v };

References

In Jet+Spot the concept of "refs" is more formally called references.

package com.business.components {
    //
    public function HelloWorld() {
        [Reference]
        var button:Button?;

        //
        Spot::useEffect(function() {
            trace(button!);
        }, []);

        return (
            <j:Button bind={button}>click me</j:Button>
        );
    }
}

Contexts

Context usage is represented as Spot::ContextReflection.<T> objects, although they are used as natural Context-annotated locals.

function ExampleComponent() {
    //
    [Context(ExampleContext)]
    const example:Number;

    return (
        <></>
    );
}

Effects

The popular "useEffect" hook requires the second argument, preventing mistakes. For listening to any changes, use "*".

Spot::useEffect(function() {
    //
    return function() {
        // cleanup
    };
}, [dep1, ...depN]);

Spot::useEffect(function() {
    //
}, "*");

Styling

Unlike with React.js, there is built-in support for linking style sheets in a Spot component.

<j:Container>
    <j:Style>
        <![CDATA[
            :host {
                background: red;
            }
        ]]>
    </j:Style>
</j:Container>

More on style sheets