Effects & Reactivity
Perform side effects (API calls, timers, DOM manipulation) automatically when your state changes.
Reacting to Changes
Pass a function and a dependency array to pp.effect. The function runs whenever a variable in the array changes.
live-search.html
<div class="space-y-2">
<input
type="text"
value="{query}"
placeholder="Search users..."
oninput="setQuery(event.target.value)"
class="border p-2 rounded w-full"
/>
<p class="text-sm text-gray-500">
{isLoading ? 'Searching...' : results.length + ' results found.'}
</p>
</div>
<script type="text/pp">
const [query, setQuery] = pp.state("");
const [results, setResults] = pp.state([]);
const [isLoading, setLoading] = pp.state(false);
// Run this effect whenever 'query' changes
pp.effect(() => {
if (!query) {
setResults([]);
return;
}
setLoading(true);
// Simulate an API call
setTimeout(() => {
const mockDB = ["Alice", "Bob", "Charlie", "Dave"];
const filtered = mockDB.filter(n =>
n.toLowerCase().includes(query.toLowerCase())
);
setResults(filtered);
setLoading(false);
}, 500);
}, [query]); // <-- Dependency Array
</script>
Cleanup & Lifecycle
If your effect creates a resource (like a Timer or Event Listener), return a cleanup function. PulsePoint runs this function before re-running the effect or when the component unmounts.
Memory Leaks: Always return a cleanup function for
setInterval, addEventListener, or WebSocket connections.
stopwatch.html
<div>
<p class="text-2xl font-mono">Time: {seconds}s</p>
<div class="flex gap-2 mt-2">
<button onclick="setRunning(true)" disabled="{isRunning}">Start</button>
<button onclick="setRunning(false)" disabled="{!isRunning}">Stop</button>
</div>
</div>
<script type="text/pp">
const [seconds, setSeconds] = pp.state(0);
const [isRunning, setRunning] = pp.state(false);
pp.effect(() => {
// Only set up the timer if we are running
if (isRunning) {
const timerId = setInterval(() => {
setSeconds(s => s + 1); // Functional update usually safer
}, 1000);
// CLEANUP: Runs when isRunning changes to false, or component dies
return => clearInterval(timerId);
}
}, [isRunning]);
</script>
Dependency Array Cheat Sheet
Control exactly when your effect runs by adjusting the second argument.
| Syntax | Behavior |
|---|---|
| pp.effect(fn, [prop]) | Runs on mount, and whenever prop changes. |
| pp.effect(fn, []) | Runs once on mount. (Great for initial API calls). |
| pp.effect(fn) | Runs on every render. (Use with caution). |