Signal Arrays do not work with HTML-Elements?

I tried to debug my problem for a while until I realized that this works:
import { useSignal } from "@preact/signals";

export default function Island() {
const activated = useSignal(false);
return (
<button
onClick={() => {
activated.value = !activated.value;
}}
class={activated.value ? "bg-blue-800" : "bg-red-800"}
>
Test
</button>
);
}
import { useSignal } from "@preact/signals";

export default function Island() {
const activated = useSignal(false);
return (
<button
onClick={() => {
activated.value = !activated.value;
}}
class={activated.value ? "bg-blue-800" : "bg-red-800"}
>
Test
</button>
);
}
but this does not:
import { useSignal } from "@preact/signals";

export default function Island() {
const activated = useSignal([false]);
return (
<button
onClick={() => {
activated.value[0] = !activated.value[0];
}}
class={activated.value[0] ? "bg-blue-800" : "bg-red-800"}
>
Test
</button>
);
}
import { useSignal } from "@preact/signals";

export default function Island() {
const activated = useSignal([false]);
return (
<button
onClick={() => {
activated.value[0] = !activated.value[0];
}}
class={activated.value[0] ? "bg-blue-800" : "bg-red-800"}
>
Test
</button>
);
}
A
AwsmBuff279d ago
This is just an example but in my project: Being able to use an array at that point instead of hardcoding all the signals would help me a lot. Am I using it wrong?
I
ioB279d ago
You need to make sure to set the actual signal value alternatively, you could have an array of signals
A
AwsmBuff279d ago
At first: Thank you for your help! What do you mean by that? I thought I am setting the signal value with activated.value[0] = !activated.value[0];. At least that is what I am doing in the first example and there it works. Yea, that is what I am now trying to do but it gets ugly in my case and I wondered if an array inside of a signal would work too.
I
ioB279d ago
preact signals don’t do deep observability. You can do what you’re doing right now, but you need to reassign the array afterwards. activated.value = activated.value should work it’s similar to svelte state if you’ve ever done that before
A
AwsmBuff279d ago
Reassign like right after negating the value? (Just asking because I tried that and it did not work.) Doesn't sound familiar to me 😅
I
ioB279d ago
marvin probably knows better than me 😅
M
marvinh.279d ago
yup, like lino said: Signals track reactivity through assignment. That means a signal will only update when you do signal.value = whatever . Pushing into an array or mutating the contents of the array is not tracked. Assigning to an index in the array assigns to the array, not the signal. So it's not tracked. We thought about doing deep tracking like this when creating signals, but ultimately you always end up having to Proxy every collection type in JS like Array, Map, Set,... which gets a bit nasty with edge cases. Add on top that it blurs the line between when something is tracked and when it's not. So we opted for the simpler model. @lino-levan nah you're already spot on. Just providing a little more historic context 😄
A
AwsmBuff279d ago
Thank you very much for the detailed explanation. Would you recommend to do an array of signals instead a signal containing an array then too or is there a better way?
M
marvinh.279d ago
Depends on what parts of the data you want to react to in your UI. If you only ever deal with the full array you can just clone it and assign it to update it.
const next = activated.value.slice(); // clone old array
next[0] = !activated.value[0]; // update value
activated.value = next; // trigger signals update
const next = activated.value.slice(); // clone old array
next[0] = !activated.value[0]; // update value
activated.value = next; // trigger signals update
some devs also may use destructuring to clone arrays. Both work the same way
const next = [...activated.value]
const next = [...activated.value]
A
AwsmBuff279d ago
Cool, thanks again for the suggestions! And @lino-levan for the first aid! Hope this will help others in the future as well.
More Posts
Reuse Deno.serve for other TCP connectionsHello, As a newcommer to Deno, I wrote a client for NNTP protocol (https://github.com/sntran/deno_ndeno coverage crashI run ``` deno test -A --coverage=tmp/coverageData src ``` then ``` deno coverage --include=src/ tmpIs there a way to copy an element and place it somewhere else?Link: https://stackoverflow.com/questions/76704496/is-there-a-way-to-copy-an-element-and-place-it-sonot sure why this code is erroring```typescript for (const number of genNumbers()) { const result = await fetchPages(number); if (Why doesn't POST response from serveTls support streaming chunks from a ReadableStream?We can POST a ReadableStream to a serveTls server, however when we respond with a ReadableStream theWhen I use npm: node: specifiers how can I specify the version?We know in Deno we can do `import { Client, Pool } from "https://deno.land/x/pg@v0.6.1/mod.ts";` I wFakeTime seems to break async testsI am attempting to use FakeTime similarly to in the Faking time example of https://deno.land/manual@How to serve HTTPS with the Deno.serve() APII used to start a dev server with TLS like so ```const server = Deno.listenTls({ port: 7000, trCustom console.log formatting for a class/objectIs there a way to change the way an object/class is printed in the console? For example, instead ofIs there a way to write to a file by replacing bytes?Like "I am a looong file" > write('Test') > 'Test a looong file'std/http/server: URI too long —how to avoid loading those?Using https://deno.land/std@0.194.0/http/server.ts, is there a way to reject long URIs before they aWorker: TS2304 [ERROR]: Cannot find name 'postMessage'When type-checking a worker script that uses the global `postMessage()` method, `deno check` gives aHow to recover from worker death? It terminates my main program…In the error message handler, I replace the dead worker with a new one, but it kills my program eithIs there anyone using kv with pentagon ORM and Zod ?I've tried using pentagon for Deno kv in a Fresh project, and it seems like it's not working.Prefix Kv keys with a base partCurrently I add `base()` to all keys: ``` kv.set([base(), "foo"], value) ``` Instead of manually adCaching old versionsWhy is deno caching old versions even tho the version is specifieddeno check: Module '"internal:///missing_dependency.d.ts"' has no exported member...The sequence of events: - Upgraded to Deno 1.35.0 - ran `deno check` on my code - got an error like cargo compile size 160MWhen using `cargo install deno` the result is 160M, if there's info on shrinking this somewhere pleaDeno type enforcementHey, I have a question about the type checking. ```ts function logging(message : number) { consoDNS Records and Denoso I am confused I'm building an application that uses Steam's web API and am looking at why the res