useDeepCompareEffect in solid

How would I do something like this in solid-js (would I do this)?
/**
* Same as `React.useEffect` but uses a deep comparison on the dependency array. This should only
* be used when working with non-primitive dependencies.
*
* @param effect Effect callback to run
* @param deps Effect dependencies
*/
export function useDeepCompareEffect(effect: React.EffectCallback, deps: React.DependencyList) {
const ref = useRef<React.DependencyList>(deps)

// Only update the current dependencies if they are not deep equal
if (!isEqual(deps, ref.current)) {
ref.current = deps
}

// eslint-disable-next-line react-hooks/exhaustive-deps
return useEffect(effect, ref.current)
}
/**
* Same as `React.useEffect` but uses a deep comparison on the dependency array. This should only
* be used when working with non-primitive dependencies.
*
* @param effect Effect callback to run
* @param deps Effect dependencies
*/
export function useDeepCompareEffect(effect: React.EffectCallback, deps: React.DependencyList) {
const ref = useRef<React.DependencyList>(deps)

// Only update the current dependencies if they are not deep equal
if (!isEqual(deps, ref.current)) {
ref.current = deps
}

// eslint-disable-next-line react-hooks/exhaustive-deps
return useEffect(effect, ref.current)
}
8 Replies
thetarnav
thetarnav2y ago
1. a normal effect with the prev parameter used in the callback 2. read from signal/signals that you wish to track 3. compare them how you want if they match, return early prev value if they do not match, do your logic and return new value You can also use a memo as a cashe/equality check layer with passing the equals option to it
apollo79
apollo79OP2y ago
Sry, but I don't get it. Could you write it up? It doesn't sound complicated, but... idk
thetarnav
thetarnav2y ago
const v2 = createMemo(() => v1(), undefined, {
equals: (a, b) => isEqual(a, b)
})
const v2 = createMemo(() => v1(), undefined, {
equals: (a, b) => isEqual(a, b)
})
apollo79
apollo79OP2y ago
So this would do it:
export function createDeepCompareEffect(effect: () => void, deps: Accessor<ReadonlyArray<unknown>>) {
const result = createMemo(() => deps(), undefined, {
equals: (a, b) => isEqual(a, b),
});

createEffect(on(result, effect));


return result;
}
export function createDeepCompareEffect(effect: () => void, deps: Accessor<ReadonlyArray<unknown>>) {
const result = createMemo(() => deps(), undefined, {
equals: (a, b) => isEqual(a, b),
});

createEffect(on(result, effect));


return result;
}
Since I want to execute this effect callback.
thetarnav
thetarnav2y ago
Sure it kills computability a bit, but should work
apollo79
apollo79OP2y ago
I don't know if it is a good solution. It's a bit different in React. I feel like deps should have a different type, but that would kill reactivity, wouldn't it?
thetarnav
thetarnav2y ago
createDeepCompareMemo would probably be a more universal abstraction
mdynnl
mdynnl2y ago
on(deps, (a, b, c) => dequal(a, b) ? c : fn(a, b, c))
Want results from more Discord servers?
Add your server