The features described in this article are still in an early stage of development. The behaviour might change significantly in the future and the functionality could be completely removed.
DATEX JS has a fine-grained reactivity model that provides inherent reactivity for values wrapped with $$()
.
Updating reactive values works exactly the same as with normal values:
const x = $$({a: 41, b: 42});
x.a = 43;
Reactive computations can be defined with special transform functions:
import { add } from "unyt_core/functions.ts";
const a = $$(1);
const b = $$(2)
const sum = add(a, b); // Datex.Ref<3>
Alternatively, you can use the generic always()
transform function containing vanilla JavaScript operations:
const a = $$(1);
const b = $$(2)
const sum = always(() => a + b); // Datex.Ref<3>
Primitive reactive values can directly be passed to JSX elements:
const x = $$("Hello");
export default <div>{x}</div>
To bind live object properties to a JSX element, the $
property syntax is required:
const x = $$({content: "Hello"});
export default <div>{x.$.content}</div>
You can achieve the same behaviour using always()
:
const x = $$({content: "Hello"});
export default <div>{always(() => x.content)}</div>
With the new experimental embedded JSX reactivity feature, it is no longer required to explicitly
use always()
inside JSX definitions. The example above can be simplified to:
const x = $$({content: "Hello"});
export default <div>{x.content}</div>
This also works with more complex expressions:
const show = $$(false);
export default <div>{show ? "Hello World" : ""}</div>
const counter = $$(0);
export default <div>Next Value: {counter + 1}</div>
For reactivity outside of JSX definitions, we are introducing the new $()
shorthand function
which could replace both the $$()
and the always()
function in the future.
Example using $$()
and always()
:
const x = $$(10);
const y = always(() => x * 2);
This can now be written using $()
:
const x = $(10);
const y = $(x * 2);
Both the new JSX reactivity and the $()
syntax are extending
the TypeScript/TSX standard and do not work in a default TypeScript/TSX
implementation.
They are implemented with SWC plugins and work like macros that are transformed at compile time.
Embedded JSX reactivity is currently internally provided with always()
transforms that are not as efficient as dedicated transform functions or $
methods:
const list = $$([...]);
// new embedded JSX reactivity
export default <div>{list.map(item => item.name)}</div>
// $ method (more efficient)
export default <div>{list.$.map(item => item.name)}</div>
This will be improved in the future.
Currently, the $()
syntax as well as the embedded JSX reactivity functionality
are not enabled per default.
If you want to try out these features, you can enable them as experimental features in
your app.dx
file:
name: "My App",
experimentalFeatures: ['embedded-reactivity'];
Keep in mind that the embedded reactivity features are currently only supported for frontend modules.
Please report any issues on https://github.com/unyt-org/uix or https://github.com/unyt-org/jusix.