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
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
.
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:
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
.
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.
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.