Skip to main content

Quick Start

Welcome to the State documentation!

In this guide, we’ll create a basic To-Do App to demonstrate how to create a state driven UI using State.

Setup​

Clone the example repository:

git clone <URL>

Enter to the project folder and install the dependencies:

npm i @uiless.io/state

Run the project:

npm run dev
info

Open localhost:5173 in the browser to see the project running.

Creating the TodoApp class​

Inside src/state/TodoApp.js add a TodoApp class that extends State.

src/state/TodoApp.js
import { State } from '@uiless.io/state';

export class TodoApp extends State {
constructor() {}
}

Create the initial state value for TodoApp and pass it to the State constructor using super keyword.

const initialTodoApp = {
todos: [],
};

export class TodoApp extends State {
constructor() {
super(initialTodoApp);
}
}

Declare the methods for adding and removing todos.

export class TodoApp extends State {
...

addTodo = (text) => {};

removeTodo = (id) => {};
}

Add the logic to update the state using the method from the parent class this.update, it uses immer to modify the current state.

export class TodoApp extends State {
...

addTodo = (text) => {
this.update((state) => {
state.todos.push({ id: crypto.randomUUID(), text });
});
};

removeTodo = (id) => {
this.update((state) => {
state.todos = state.todos.filter((todo) => todo.id !== id);
});
};
}

The full code should look like this:

src/state/TodoApp.js
import { State } from '@uiless.io/state';

const initialTodoApp = {
todos: [],
};

export class TodoApp extends State {
constructor() {
super(initialTodoApp);
}

addTodo = (text) => {
this.update((state) => {
state.todos.push({ id: crypto.randomUUID(), text });
});
};

removeTodo = (id) => {
this.update((state) => {
state.todos = state.todos.filter((todo) => todo.id !== id);
});
};
}

Implementing the TodoApp state​

Inside src/state/index.js.

src/state/index.js
import { TodoApp } from './TodoApp';

export const todoApp = new TodoApp();

The instance todoApp holds all the logic that allow you update the state in a controlled and centraliced way. It can be used and shared between any UI framework component.

Integrating with the UI​

You have written all the business logic and state behavior in plain js without a UI framework. It is time to integrate it into the UI.

We are using React as UI framework for this example. Install the @uiless.io/state-react package:

npm i @uiless.io/state-react

Update the App component.

src/app.js
import { useSubscribe } from '@uiless.io/state-react';
import { todoApp } from './state';
import stateLogo from './assets/state.webp';
import './App.css';

function App() {
const { todos } = useSubscribe(todoApp);

return (
<div className="container">
<section className="hero">
<a href="https://state.uiless.io" target="_blank">
<img src={stateLogo} className="logo" alt="State logo" />
</a>
<h1>State</h1>
<p>
Edit <code>src/App.jsx</code>
</p>
<p className="text">Click on the State logo to learn more</p>
</section>
<section className="todo">
<h2>To-Do List</h2>
<p className="text">Write a text for the To-Do and press enter</p>
<input
type="text"
id="todo-input"
placeholder="Example"
onKeyDown={(event) => {
if (event.key === 'Enter') {
todoApp.addTodo(event.target.value);
event.target.value = '';
}
}}
/>
{todos.map((todo) => (
<div className="todo-card" key={todo.id}>
{todo.text}
</div>
))}
</section>
</div>
);
}

export default App;

It is time to test. Go to localhost:5173 and enter a value on the input, then press Enter.