State and Redux

An interactive project contains many moving pieces that constantly change and oftentimes the UI is expected to reflect these changes. We call the collection of system, environment and project data the “Global State”. This state serves as the one source of truth in order to maintain coherency while developing and running the project.

The Global State is saved in a Redux state. This state includes all data of the player and its plugins and is easily accessible from both the player API as well as within react components in the UI system. Let’s explore how to use the global state while developing UI components.

See the Debugging tutorial to learn how to use Redux devtools.

The store

The store is a global object that is responsible of exposing and changing the state.
The UI plugin already passes the global store to all its components via this.props.globalState. If you need to access the store from outside a UI component, you can do so via the player’s reduxStore property and the getState() method.

At a given point in time the store object could look something like this

// Example: partial defintion.
{
  player: {
    volume: 1,
    muted: false,
    isPlaying: true,
    isPaused: false,
    isSeeking: false,
    ...
  },
  decision: {
    myParentNodeId: {
      parent: 'myParentNodeId',
      children: ['myFirstChild', 'mySecondChild'],
      defaults: ['myFirstChild'],
      state: 'inactive',
      time: 0,
      duration: 7.485011000000002,
      progress: 0,
      remainingTime: 7.485011000000002,
      selected: {}
    },
    ...
  },
  ui: {
    controllers: {
      myParentNodeId: {
        controllerType: 'DECISION',
        visible: false,
        decisionActive: false,
        inLingerTimeout: false
      },
      ...
    }
  },
  sparks: {
    visible: false
  },
  subtitles: {
    visible: false,
    text: 'To be, or not to be, that is the question',
    availableLanguages: {
      en: {
        nativeName: 'English',
        englishName: 'English'
      }
    },
    language: '',
    effectiveLanguage: 'en',
    style: {}
  },
  variables: {
    myVarName: 'myVarValue',
    ...
  }
}

More details about the different sub-objects of the redux globalState can be found here:

Let’s take a look at a real code example.

Code example

Suppose we want to create a UI component for your project which displays the player’s current node time as it changes. We’ll be using currentNodeTime property from player state object in the component’s render() method.

The benefit of doing it this way is that your UI component will re-render automatically when the player current node time value changes so you don’t need to take care of that yourself!
Here is how the code for this component would look like:

App.js

import React from 'react';
import 'MyNodeTime.scss';

export default function onInit(player, context) {  
    class MyNodeTime extends React.Component {
        render() {
            let playerReduxState = this.props.globalState.player; 
            let currentNodeTime = playerReduxState.currentNodeTime;
            let currentNodeTimeFormatted = currentNodeTime.toFixed(2);

            return <div className='myNodeTime'>{currentNodeTimeFormatted}</div>;
        }
    }

    player.ui.add('myNodeTime', MyNodeTime);
}

MyNodeTime.scss

.myNodeTime{
    position: absolute;
    top: 20px;
    font-size: 30px;
    background-color: orange;
}

The result will be something like this:

Alt Text

Rate this page: X
Tell us more!