Component Architecture
Anchor components follow the Separation of Concerns principle, clearly dividing your application into two distinct layers:
- Component (Logic Layer) - Runs once, defines state and behavior
- View (Presentation Layer) - Runs reactively, displays UI based on state
This separation creates stable, predictable components where logic never re-executes and only the UI updates when state changes.
import { setup, render, mutable } from '@anchorlib/react';
// ━━━ COMPONENT (Logic Layer) ━━━
export const Counter = setup((props) => {
// State and logic - runs once
const state = mutable({ count: 0 });
const increment = () => {
state.count++;
};
// ━━━ VIEW (Presentation Layer) ━━━
// Runs reactively when state.count changes
return render(() => (
<button onClick={increment}>
Count: {state.count}
</button>
));
}, 'Counter');Component: The Logic Layer
The Component is your constructor—a container for state, logic, and effects. It runs exactly once when the component is created, providing a stable foundation for your UI.
A Component defines:
- State - Reactive data that persists for the component's lifetime
- Logic - Functions and computations that operate on state
- Effects - Side effects that respond to state changes
Because the Component runs only once, your functions are stable and always reference the current state—no stale closures, no dependency arrays.
View: The Presentation Layer
The View displays your data to users. It's reactive—automatically tracking which state properties it reads and re-rendering only when those specific properties change.
A Component can have:
- Component View - The primary reactive View returned immediately, tied to the Component's output.
- Templates - Standalone, reusable Views that rely on props.
- Snippets - Scoped Views defined inside the Component with access to its state.
Why Separation of Concerns?
In standard React, logic and view are tightly coupled—the component function re-executes on every render, recreating functions, recalculating values, and requiring complex patterns like useCallback, useMemo, and dependency arrays to maintain stability. This coupling creates several problems:
- Stale closures - Functions capture outdated state, causing subtle bugs
- Performance overhead - Expensive logic re-runs unnecessarily on every render
- Hard to read - Logic and view mixed together makes code difficult to understand and maintain
- Complexity - Dependency arrays and memoization add cognitive load and maintenance burden
These problems force developers to spend more time debugging, optimizing, and maintaining code instead of building features—directly impacting productivity.
Anchor's Separation of Concerns solves these problems:
Stability
Component logic runs once and stays stable. Functions, event handlers, and effects are never recreated—your functions always reference the current state without stale closures or dependency arrays.
Performance
Only the View re-runs when state changes. The Component (containing your expensive initialization, computations, and business logic) never re-executes.
Readability
Logic and view are clearly separated. You can read the Component to understand what the component does, and read the View to understand what it looks like—no more mental parsing of mixed concerns.
Simplicity
No useCallback, no useMemo, no dependency arrays. Write straightforward code and let the architecture handle optimization automatically.
The result: developers spend less time debugging, optimizing, and maintaining—and more time building features.
Core Concepts
- Component - Creating the Logic Layer
- View & Template - Creating the Presentation Layer
- Lifecycle - Component lifecycle and effects
- Binding & Refs - Interacting with DOM elements