Unit 2: State

An app is a living entity, it is updated with every interaction from the user or the database. If we would take a snapshot of the app, the state describes the value for that moment in time of all the parameters that govern its behavior. Thus, the state can be regarded as the collection of variables that govern the behavior and appearance of the app. Let’s begin with a simple example; an app with a text input that we will use to update the name of the user. In this case, userName is the only state variable required.

/* Imports */
import {app, read, update} from '@onejs-dev/core';
import {View, Text, Input} from '@onejs-dev/components';

/* App Component: Takes no properties and returns structure */
const App = () => {
return View({content: {direction: 'column'}})([
Text()('User Name: '),
Input({
type: 'text',
placeholder: 'Name'
})
]);
};

/* App Function: Renders the App Component in the screen */
app({component: App, theme: {preset: 'oneJS'}});

Declaration

The first step is to declare all the state variables of the app as a configuration object. The object takes as keys the state variable ids. The value, is an object that can take the following properties:

default

The default value for the state variable. If no other value is retrieved or set, this will be its initial value. The default value can be provided as an object property or as a string:

/* State Configuration */
const state = {
userName: {default: 'my name'}
};
/* State Configuration */
const state = {
userName: 'my name'
};

source and storage

source, represent the origin for the value of the state variable. storage is the location where the state variable’s value is saved. They can take the following values:

/* State Configuration */
const state = {
    userName: {        
        source: {local: 'userName'}, 
        storage: {local: 'userName'}
    }
};

/* State Configuration */
const state = {
    userData: {
        source: {firestore: 'users/id1234'}, 
        storage: {firestore: 'users/id1234'}
    }
};

/* State Configuration */
const state = {
    page: {
        source: {url: 'path/*/:'}, 
        //Actual url = 'path/to/home' --> page = 'home';
        //Actual url = 'other/path --> page = undefined;
    }
};

Once the configuration object is created, feed this value to the app function’s state property.

/* State Configuration */
const state = {
    userName: {default: 'my name'}
}; 
app({component: App, state: state});

Read

Once the state is defined, we need a means of accessing it. oneJS provides the read function that returns the state variable’s current value for the selected state id; in this case userName. Now in the example we can check how the default value of the state variable is applied to the input, but we still need a way for the input to update its value. Learn about it in the following section.

/* Imports */
import {app, read} from '@onejs-dev/core';
import {View, Text, Input} from '@onejs-dev/components';

/* State Configuration */
const state = {
    userName: ''
}; 

/* App Component: Takes no properties and returns structure */
const App = () => {
    return  View({content: {direction: 'column'}})([
        Text()('User Name: ' + read('userName')),
        Input({
            type: 'text', 
            placeholder: 'Name',
            value: read('userName'),
        })
    ]);
};

/* App Function: Renders the App Component in the screen */
app({component: App, state: state, theme: {preset: 'oneJS'}});

Update

In functional programming, functions should not directly update the state. This would break their isolation as they would need to “be aware” of the context where they are called in. On the other hand, an app unable to change its state would be unusable. In oneJS, while functions will never directly access the state, we allow the user to bind to the component event functions such as the onChange event. You can pass a function to the onChange property that reads the event’s changed value and uses it to update the state. Exactly for this purpose, oneJS provides the update function; it takes as first parameter the name of the state variable to be updated and automatically updates the state when the onChange event is triggered.

/* Imports */
import {app, read, update} from '@onejs-dev/core';
import {View, Text, Input} from '@onejs-dev/components';

/* State Configuration */
const state = {
    userName: ''
}; 

/* App Component: Takes no properties and returns structure */
const App = () => {
    return  View({content: {direction: 'column'}})([
        Text()('User Name: ' + read('userName')),
        Input({
            type: 'text', 
            placeholder: 'Name',
            value: read('userName'),
            onChange: update('userName'), 
        })
    ]);
};

/* App Function: Renders the App Component in the screen */
app({component: App, state: state, theme: {preset: 'oneJS'}});