Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ReactJS

ShockScript embeds the XML language closely as the E4X standard, however XML literals allow for implementations to produce anything desired based on type inference. The Whack DS framework for ShockScript, a reactive UI layer over the DOM, is based on the ReactJS principles and uses E4X constructs that may remind of JSX.

There are, however, many positive differences to ReactJS, such as memoization and auto dependency tracking.

HelloWorld.sx

package zero {
    import whack.ds.UIComponent;
    import s = spark.components.*

    public class HelloWorld extends UIComponent {
        public function HelloWorld() {
            super()
            final = (
                <s:Application>
                    <s:Label>Hello World!</s:Label>
                </s:Application>
            );
        }
    }
}

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 @event tag.

When specifying event handlers, note that the callback is cached only if .

Prefixes

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

<zero.components.AppBar/>

For brevity, you do either:

import zx = zero.components.*;

xn = <zx:AppBar/>

or:

import zero.components.*

xn = <AppBar/>

Interpolation

Interpolation works similiarly to ReactJS, except for HTML.

<div>
    {undefined}
    {null}
    {node}
    {node_list}
    {plain_text}
    {number}       <!-- The Number union -->
    {boolean}
</div>

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

<button {arguments}>click me</button>

Component definition

Components are defined as classes extending the UIComponent class and not regular functions. It is far different from ReactJS legacy class components.

States

Unlike ReactJS, in Whack DS there is no risk of accessing an outdated state’s value, due to how states are constructed.

package spark.components {
    import whack.ds.UIComponent;

    public class Ark extends UIComponent {
        [State]
        var x : uint = 0;

        public function Ark() {
            super();
            final = (
                <w:VGroup>
                    <span>clicked {x} times</span>
                    <button click&={x++}>click me</button>
                </w:VGroup>
            );
        }
    }
}

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

Like ReactJS, 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 };

Bindables

In Whack DS the concept of “refs” is called bindables.

package spark.components {
    import whack.ds.UIComponent;

    public class Ark extends UIComponent {
        [Bindable]
        var button : org.w3.web.Button? = null;

        public function Ark() {
            super();

            whack.ds.useEffect(function() {
                trace(button!.@x);
            });

            final = (
                <button bind={button}>click me</button>
            );
        }
    }
}

Note .@x is a meta-data attribute accessor for DOM elements.

Contexts

Using contexts results in ContextReference.<T> objects, although they are used as natural Context-annotated variables.

public class View extends UIComponent {
    [Context("zero.contexts.Example")]
    const example;

    public function View() {
        super()
        final = (
            <></>
        )
    }
}

Props

Props must be typed tap {}. It is not recommended to destructure Props.

public class View extends UIComponent {
    public function View(props : Props) {
        super()
        final = (
            <></>
        )
    }

    public type Props = tap {
        /** @event */
        next? : function() : void,
    }
}

Effects

The popular “useEffect” hook, differently from ReactJS, auto tracks dependencies, preventing mistakes. For listening to any changes, use "*".

whack.ds.useEffect(function() {
    //
    return function() {
        // Cleanup
    };
});

whack.ds.useEffect(function() {
    //
}, "*");

Styling

Unlike with ReactJS, there is built-in support for linking style sheets in a Whack DS component.

<div>
    <fx:Style>
    <![CDATA[
        root {
            background: red
        }
    ]]>
    </fx:Style>
</div>

Callbacks

Callbacks are cached within XML attributes for memoization, if it matters.

Helpful resources