Replies: 6 comments
-
import { useSignal, useComputed, useSignalEffect } from "@preact/signals-react";
import { useLinkedSignal } from "@preact-signals/utils/hooks";
export function Counter({ multiplier }: { multiplier: number }) {
const countSignal = useSignal(0);
const multiplierSig = useLinkedSignal(multiplier);
const total = useComputed(() => multiplierSig.value * countSignal.value);
useSignalEffect(() => {
localStorage.setItem("countWithMultiplier", `${total.value}`);
});
return (
<div>
{total}
<button onClick={() => countSignal.value++}>Add One</button>
</div>
);
} https://tsdocs.dev/docs/@preact-signals/utils/0.14.1#md:uselinkedsignal Here is implementation of linked signal: https://github.com/XantreGodlike/preact-signals/blob/main/packages/utils/src/hooks/useLinkedSignal.ts |
Beta Was this translation helpful? Give feedback.
-
Expecting official lint rules to work with an unofficial state primitive seems a tad bit overly hopeful to me. If you want to restrict yourself to lint rules that aren't fully aware of the context of your code, then you may need to use one of your workarounds. I don't think adding a dep array to As mentioned, you could just make your non-signal prop into a signal. I know you have a simplified example there, so that might not be viable all the time, but is an option.
It sorta is but certainly not well. I think our docs here need some time investment for sure (and the Preact site needs a note saying it's mainly centered around Preact usage, but I digress). |
Beta Was this translation helpful? Give feedback.
-
Just spitballing here, but how about a separate eslint plugin/rule based on |
Beta Was this translation helpful? Give feedback.
-
Sounds like a reasonable solution, but I don't think we have any interest or capacity to build/maintain that, if that's what you're asking. |
Beta Was this translation helpful? Give feedback.
-
That's understandable, I think I'll take a crack at it when I have some free time. |
Beta Was this translation helpful? Give feedback.
-
I found some free time, here's the eslint plugin: https://github.com/JonAbrams/eslint-plugin-react-hooks-signals |
Beta Was this translation helpful? Give feedback.
-
I'm using
@preact/signals-react
along with the babel transformer and am running into an issue with React'suseEffect
. The official react lint rulereact-hooks/exhaustive-deps
doesn't play nicely with signals.Consider this example:
The above will fail the
react-hooks/exhaustive-deps
check becausecountSignal.value
in the list of useEffect dependencies is declared an error:I know that there exists a
useSignalEffect
hook to allow a component to run side effects on a signal's change, but it's only for signals, it can't trigger on prop changes too (like in the example).This can be worked around by assigning the value to a local variable first (
const countValue = countSignal.value
), but that's annoying. Plus before you even remember to do that, an eslint autofix would just silently remove thecountSignal.value
dependency from useEffect, leading to a potential bug.One potential fix could be to add an optional dependency array to
useSignalEffect
so that it can also trigger on non-signal changes. Also,useSignalEffect
isn't documented, so there's that too.Update: Fixed example, now using a signal created out of scope of the component to reflect the actual case were the linter raises a warning.
Beta Was this translation helpful? Give feedback.
All reactions