Skip to content

✅ Todo List Example

This example demonstrates how to build a fully reactive todo list with Atomix and React. You'll see how to:

  • Store and update a list of items
  • Add, remove, and toggle todos
  • Automatically re-render based on subscriptions

🧱 1. Define the Atom

ts
// atoms/todo.ts
import { createAtom } from "atomix-core";

export type Todo = {
  id: number;
  text: string;
  completed: boolean;
};
export interface InitalStat {
  todos: Todo[];
}
export interface Actions {
  addTodo: (text: string) => void;
  toggleTodo: (id: number) => void;
  removeTodo: (id: number) => void;
}
let nextId = 1;
export const todoAtom = createAtom<InitalStat, Actions>(
  {
    todos: [] as Todo[],
  },
  (set) => ({
    addTodo: (text: string) =>
      set((s) => ({
        todos: [...s.todos, { id: nextId++, text, completed: false }],
      })),
    toggleTodo: (id: number) =>
      set((s) => ({
        todos: s.todos.map((todo) =>
          todo.id === id ? { ...todo, completed: !todo.completed } : todo
        ),
      })),
    removeTodo: (id: number) =>
      set((s) => ({ todos: s.todos.filter((el) => el.id !== id) })),
  })
);

⚛️ 2. Provide to Your Componet Tree

ts
// App.jsx
import { AtomixProvider } from "atomix-react";
import { todoAtom } from "./atoms/todo";
import { TodoList } from "./components/TodoList";
export default function App() {
  return (
    <AtomixProvider store={todoAtom}>
      <TodoList />
    </AtomixProvider>
  );
}

⚛️ 3. Use It in a React Component

tsx
// components/TodoList.tsx
import { useAtom, useActions } from "atomix-react";
import type { Actions, InitalStat, Todo } from "./atom/todo";
import { useState } from "react";

export function TodoList() {
  const [text, setText] = useState("");
  const todos: Todo[] = useAtomx((s: InitalStat) => s.todos);
  const { addTodo, removeTodo, toggleTodo }: Actions = useActions();

  return (
    <div style={{ maxWidth: 400, margin: "0 auto" }}>
      <h2>Todo List</h2>
      <input
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="New todo"
      />
      <button onClick={addTodo} disabled={!text}>
        Add
      </button>

      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            <span
              onClick={() => toggleTodo(todo.id)}
              style={{
                textDecoration: todo.completed ? "line-through" : "none",
                cursor: "pointer",
              }}
            >
              {todo.text}
            </span>
            <button
              onClick={() => removeTodo(todo.id)}
              style={{ marginLeft: "1rem" }}
            >

            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

🔍 Notes

Every mutation is handled through Actions recived from useActions hook.

useAtom ensures minimal re-renders.

v1.0.2 • Released under the MIT License.