Chad Steele
Chad Steele
SSolidJS
Created by Chad Steele on 2/27/2025 in #support
I want to debounce a signal for some effects, but not others
In short, I'm using a slider to allow the user to quickly adjust font scale linearly. I need the font to respond to the 1000s of adjustments, but I do not want to update the history buffer with every minor font change that the slider will trigger. I tried to get the primitives to work, but failed to find a way to have both instant and bounced effects without having to write a lot of code. https://primitives.solidjs.community/package/scheduled#debounce My solution is pretty basic, but works well. I'm curious if there's a better way.
import {createSignal} from "solid-js"
export function debouncedSignal(value, delay = 500) {
const [signal, setSignal] = createSignal(value)
const [debounced, setDebounced] = createSignal(value)
let time = Date.now()

function set(value) {
const now = Date.now()
if (now - time > delay) {
time = now
setDebounced(() => value)
}
setSignal(() => value)
}
return [signal, set, debounced]
}
import {createSignal} from "solid-js"
export function debouncedSignal(value, delay = 500) {
const [signal, setSignal] = createSignal(value)
const [debounced, setDebounced] = createSignal(value)
let time = Date.now()

function set(value) {
const now = Date.now()
if (now - time > delay) {
time = now
setDebounced(() => value)
}
setSignal(() => value)
}
return [signal, set, debounced]
}
In this way, you can use the signal normally or the debounced value. For example,
const [size, setSize, debouncedSize] = debouncedSignal(0)

createEffect(()=>{
size() // will trigger instantly
})

createEffect(()=>{
debouncedSize() // will trigger every 500 ms
})
const [size, setSize, debouncedSize] = debouncedSignal(0)

createEffect(()=>{
size() // will trigger instantly
})

createEffect(()=>{
debouncedSize() // will trigger every 500 ms
})
14 replies