Under the hood, @joystick.js/ui
includes a global state library called Cache. Similar to popular libraries like Redux, Cache allows you to create a "store" or "cache" for storing global data. It features a simple API for getting, setting, and unsetting data from a cache as well as listening for changes to a cache.
By default, Joystick initializes a cache for you and makes it accessible as a named export at global_state
(and an alias on the default joystick
export at joystick.global_state
).
Example Usage
ui/pages/store/index.js
import joystick, { global_state } from "@joystick.js/ui";
import Cart from '../../components/cart/index.js';
const Store = joystick.component({
events: {
'click [data-item-id]': (event = {}, instance = {}) => {
global_state.set((state = {}) => {
return {
...state,
cart: [
...state.cart || [],
{ id: event.target.getAttribute('data-item-id') }
],
};
});
},
},
render: ({ component }) => {
return `
<div>
<div class="store">
<button data-item-id="book">Add a Book to Cart</button>
<button data-item-id="t-shirt">Add a T-Shirt to Cart</button>
<button data-item-id="apple">Add an Apple to Cart</button>
</div>
${component(Cart)}
</div>
`;
},
});
export default Store;
In this example, we add items to the global state on button click using global_state.set()
. The updated state is stored globally and can be accessed or modified from any component.
ui/components/cart/index.js
import joystick, { global_state } from "@joystick.js/ui";
const Cart = joystick.component({
state: {
cart: [],
},
lifecycle: {
on_mount: (instance = {}) => {
global_state.on('change', (state = {}, event = '', user_event_label = '') => {
instance.set_state({ cart: state?.cart });
});
}
},
render: ({ state, each, when }) => {
return `
<div>
<div class="items">
${when(state?.cart?.length === 0, `
<p>No items in cart</p>
`)}
${when(state?.cart?.length > 0, `
<ul>
${each(state?.cart, (item) => {
return `<li>${item.id} <button>X</button></li>`;
})}
</ul>
`)}
</div>
</div>
`;
},
});
export default Cart;
Here, the Cart
component listens for changes to the global state using global_state.on()
and syncs the global cart state with its local component state.
API
Definition
global_state: {
get: (path: string) => object,
on: (
event_type: string,
callback: (existing_state: object, event: string, user_event_label: string) => void
) => void,
set: (
callback: (existing_state: object) => object,
user_event_label: string
) => void,
unset: (path: string, user_event_label: string) => void,
}
Parameters
- get function required
- Retrieve the current global state value. Optionally provide a path string (e.g., 'cart' or 'user.profile') to access a nested value.
- on function required
-
Listen for changes to the global state.
- event_type string required
- The type of event to listen for: 'set', 'unset', or 'change'.
- callback function required
- A callback function called when the event occurs. Receives the current global state, event type, and optional user event label.
- set function required
- Update the global state by passing a function that returns the updated state object. Optionally include a user event label for debugging.
- unset function required
- Unset a value from the global state. Provide a path string (e.g., 'cart') to remove a specific property, or call without a path to clear the entire state.