Runs a function immediately and re-runs it whenever any signal read inside it changes.
import { createEffect } from '@barefootjs/client'
createEffect(fn: () => void | (() => void)): void#Basic Usage
const [count, setCount] = createSignal(0)
createEffect(() => {
document.title = `Count: ${count()}`
})
setCount(1) // Effect re-runs, title becomes "Count: 1"Dependencies are tracked automatically. No dependency array is needed.
#Conditional Dependencies
Dependencies change per run. If a branch skips a signal read, that signal is not tracked for that run:
const [showName, setShowName] = createSignal(true)
const [name, setName] = createSignal('Alice')
const [count, setCount] = createSignal(0)
createEffect(() => {
if (showName()) {
console.log(name()) // name is tracked
} else {
console.log(count()) // count is tracked instead
}
})#Cleanup
Two ways to register cleanup for resources that need teardown before re-run.
#Return a function
createEffect(() => {
const timer = setInterval(() => console.log('tick'), 1000)
return () => clearInterval(timer)
})#`onCleanup`
createEffect(() => {
const timer = setInterval(() => console.log('tick'), 1000)
onCleanup(() => clearInterval(timer))
})onCleanup can be called multiple times. Cleanups run in reverse order (last registered, first called). See onCleanup for details.
#Common Patterns
#localStorage sync
const [theme, setTheme] = createSignal('light')
createEffect(() => {
localStorage.setItem('theme', theme())
})#Data fetching
const [query, setQuery] = createSignal('')
createEffect(() => {
const q = query()
if (!q) return
const controller = new AbortController()
fetch(`/api/search?q=${q}`, { signal: controller.signal })
.then(r => r.json())
.then(setResults)
onCleanup(() => controller.abort())
})When query changes, the previous fetch is aborted before the new one starts.
#Reactive attributes
The compiler generates effects for reactive attributes:
// Source
<button disabled={loading()}>Submit</button>
// Generated client JS
const [_s0] = $(__scope, 's0')
createEffect(() => {
if (_s0) { _s0.disabled = !!(loading()) }
})