Skip to main content
Version: 1.0

Derived State

The derivedState function allows you to:

  • Automatically compute derived values based on other state values.
  • Avoid unnecessary recomputation by only updating when dependencies change.
  • Improve performance in complex calculations (e.g., filtering, aggregations, price totals).

Example: Filtered Todo List (Derived State)

This automatically updates the filtered list when the state changes.

Create a file at src/components/TodoApp.tsx:

src/components/TodoApp.tsx
import { useStateGlobal, derivedState } from "state-jet";

export type Todo = { id: number; text: string; completed: boolean };

const todoState = useStateGlobal<Todo[]>("todos", []);
const filterState = useStateGlobal<"all" | "completed" | "pending">("filter", "all");

// Derived state for filtered todos
const filteredTodos = derivedState([todoState, filterState], (todos, filter) => {
if (filter === "completed") return todos.filter((todo) => todo.completed);
if (filter === "pending") return todos.filter((todo) => !todo.completed);
return todos;
});

export default function TodoApp() {
const todos = filteredTodos();

const addTodo = (text: string) => {
todoState.set([...todos, { id: Date.now(), text, completed: false }]);
};

return (
<div>
<h1>Todo List</h1>
<button onClick={() => addTodo("New Task")}>Add Todo</button>
<select onChange={(e) => filterState.set(e.target.value as any)}>
<option value="all">All</option>
<option value="completed">Completed</option>
<option value="pending">Pending</option>
</select>
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
</div>
);
}

✅ Now, filtered todos update automatically based on the selected filter! 🎉

🎯 Why Use derivedState?

FeatureWithout derivedStateWith derivedState
Manual RecalculationsYes (Recompute manually)✅ Automatic
ReactivityRequires useEffect✅ Updates only when needed
PerformanceUnoptimized✅ Only recalculates on change
Code ComplexityHigh✅ Minimal