@joystick.js/ui

State

How to define and manage component state.

When rendering Joystick components, state can be used to render arbitrary data and control the display of the component. There are three ways to work with state in a Joystick component:

  • Setting a default value for state via the state option.
  • Updating state dynamically via instance.set_state().
  • Reading the current state via the component instance or render() arguments.

When state changes, the component automatically re-renders. Use state thoughtfully to avoid unnecessary performance overhead.

Example Usage

ui/pages/index/index.js

import joystick from '@joystick.js/ui';

const Index = joystick.component({
  state: {
    tab: 'books',
  },
  events: {
    'click [data-tab]': (event = {}, instance = {}) => {
      instance.set_state({ tab: event.target.getAttribute('data-tab') });
    },
  },
  render: ({ state, when }) => {
    return `
      <div class="media">
        <ul class="tabs">
          <li data-tab="books" class="${state.tab === 'books' ? 'is-active' : ''}">Books</li>
          <li data-tab="movies" class="${state.tab === 'movies' ? 'is-active' : ''}">Movies</li>
          <li data-tab="games" class="${state.tab === 'games' ? 'is-active' : ''}">Games</li>
        </ul>
        ${when(state.tab === 'books', `
          <p>Books list...</p>
        `)}
        ${when(state.tab === 'movies', `
          <p>Movies list...</p>
        `)}
        ${when(state.tab === 'games', `
          <p>Games list...</p>
        `)}
      </div>
    `;
  },
});

export default Index;

In this example:

  • We define an initial value for state.tab using the object syntax.
  • We update that value in response to user interaction using instance.set_state().
  • We read the value in render() to determine what UI to show.

Setting default state via function

Instead of defining state as an object, you can pass a function that returns an object. This allows you to dynamically define initial state based on component props or other runtime conditions.

ui/pages/index/index.js

import joystick from '@joystick.js/ui';

const Index = joystick.component({
  state: (instance = {}) => {
    return {
      tab: instance?.props?.tab || 'books',
    };
  },
  events: {
    'click [data-tab]': (event = {}, instance = {}) => {
      instance.set_state({ tab: event.target.getAttribute('data-tab') });
    },
  },
  render: ({ state, when }) => {
    return `
      <div class="media">
        <ul class="tabs">
          <li data-tab="books" class="${state.tab === 'books' ? 'is-active' : ''}">Books</li>
          <li data-tab="movies" class="${state.tab === 'movies' ? 'is-active' : ''}">Movies</li>
          <li data-tab="games" class="${state.tab === 'games' ? 'is-active' : ''}">Games</li>
        </ul>
        ${when(state.tab === 'books', `
          <p>Books list...</p>
        `)}
        ${when(state.tab === 'movies', `
          <p>Movies list...</p>
        `)}
        ${when(state.tab === 'games', `
          <p>Games list...</p>
        `)}
      </div>
    `;
  },
});

export default Index;

Here, we use props from the component instance to define the initial state dynamically.

API

Definition

state: object | (instance: object) => object;

Parameters

state object|function
Default state for the component. Can be a static object or a function that returns an object and receives the component instance.