-
-
Notifications
You must be signed in to change notification settings - Fork 116
Description
- Check if updating to the latest version resolves the issue
current:1.3.0
Environment
- I am using
@preact/signals-core
- I am using
@preact/signals
- I am using
@preact/signals-react
- I understand usage changed in v2, and I've followed the React Integration instructions
Describe the bug
Hi, this might not be a bug as it might be obvious to some, but for me, a Preact/Signals user of two weeks, this was a bit of a gotcha as I don't think it was mentioned in the docs and a colleague told me that accessing the .value
is what causes the magic. Although in hindsight, it does make sense if I think about it. To my defense, though, I thought that it is done (the detecting of functions that access signals.value) via static code analysis, whereas it seems that it is done by actual runtime execution path. - again, it really makes sense.
To Reproduce
Please provide a link to a StackBlitz/CodeSandbox/Codepen project or a GitHub repository that demonstrates the issue.
Steps to reproduce the behavior:
// This will not work
useSignalEffect(() => {
const { id } = $currentAction.peek()
if (!id) return
const m = $allStates.value[id]
console.log(m)
}
// This will work
useSignalEffect(() => {
const m_ = $allStates.value
const { id } = $currentAction.peek()
if (!id) return
const m = m_[id]
console.log(m)
}
Expected behavior
What should have happened when following the steps above?
There are two things that could be made better
- Improve documentation to explicitly mention that a
mySignal.value
needs to be reached and accessed ("accessing"mySignal.value
is not enough if it is not reached and executed, or in other words "accessed" - a term used in the documentation, but which kind of obscures the actual message). - Create an eslint rule that would warn of this use case - a conditional signal or an early return in front of a signal
And maybe even write a recommendation to adopt this style to define signals upfront.
function fun() {
+ const value = mySignal.value
// ... much later
if (someCondition) {
// do something with mySignal here
+ console.log(value)
- console.log(mySignal.value)
}