how can I use createEffect so it doesn't rerun when certain signals change

GitHub
test/snake.tsx at main · nikitavoloboev/test
Trying new things. Contribute to nikitavoloboev/test development by creating an account on GitHub.
15 Replies
nikivi
nikivi2y ago
@lexlohr shared this code
You want createEffect(on(event, (ev) => { /* ev is the content of event() */ }))
You want createEffect(on(event, (ev) => { /* ev is the content of event() */ }))
but I am confused still how to apply it
nikivi
nikivi2y ago
SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
nikivi
nikivi2y ago
i checked docs for createEffect api
createEffect(
on(event, (ev) => {
if (event()) {
switch (event().key) {
case "w":
moveSnake(grid(), setGrid, "up", snake(), setSnake)
break
case "a":
moveSnake(grid(), setGrid, "left", snake(), setSnake)
break
case "s":
moveSnake(grid(), setGrid, "down", snake(), setSnake)
break
case "d":
moveSnake(grid(), setGrid, "right", snake(), setSnake)
break
default:
break
}
}
})
)
createEffect(
on(event, (ev) => {
if (event()) {
switch (event().key) {
case "w":
moveSnake(grid(), setGrid, "up", snake(), setSnake)
break
case "a":
moveSnake(grid(), setGrid, "left", snake(), setSnake)
break
case "s":
moveSnake(grid(), setGrid, "down", snake(), setSnake)
break
case "d":
moveSnake(grid(), setGrid, "right", snake(), setSnake)
break
default:
break
}
}
})
)
so I have this now
Alex Lohr
Alex Lohr2y ago
You can use ev instead of event()
nikivi
nikivi2y ago
ok I think it works thank you got some bugs with logic but at least it doesn't rerun many times kind of shame that on is not documented as part of createEffect it seems its a common case at least in react to attach effects to only certain values
Alex Lohr
Alex Lohr2y ago
I would also refactor this:
const directionKeys = {
w: "up",
a: "left",
s: "down",
d: "right"
}

createEffect(on(event, ev => {
const direction = directionKeys[ev.key];
if (direction) {
moveSnake(grid(), setGrid, direction, snake(), setSnake)
}
}))
const directionKeys = {
w: "up",
a: "left",
s: "down",
d: "right"
}

createEffect(on(event, ev => {
const direction = directionKeys[ev.key];
if (direction) {
moveSnake(grid(), setGrid, direction, snake(), setSnake)
}
}))
It is documented in on.
nikivi
nikivi2y ago
createEffect(
on(event, (ev) => {
const direction = directionKeys[ev.key]
if (direction) {
moveSnake(grid(), setGrid, direction, snake(), setSnake)
}
})
)
createEffect(
on(event, (ev) => {
const direction = directionKeys[ev.key]
if (direction) {
moveSnake(grid(), setGrid, direction, snake(), setSnake)
}
})
)
breaks sadly
nikivi
nikivi2y ago
nikivi
nikivi2y ago
I still need to wrap ev to check it exists
createEffect(
on(event, (ev) => {
if (ev) {
const direction = directionKeys[ev.key]
if (direction) {
moveSnake(grid(), setGrid, direction, snake(), setSnake)
}
}
})
)
createEffect(
on(event, (ev) => {
if (ev) {
const direction = directionKeys[ev.key]
if (direction) {
moveSnake(grid(), setGrid, direction, snake(), setSnake)
}
}
})
)
so this works kind of ugly but I guess needed
Alex Lohr
Alex Lohr2y ago
Or you filter event right where you get it.
nikivi
nikivi2y ago
yea was going to say but didn't want to bother you more your solution didn't work if (ev) at top works or rather nvm
Alex Lohr
Alex Lohr2y ago
Or use createMemo to create a derived event:
const keyEvent = createMemo(last => event().key ? event() : last)
const keyEvent = createMemo(last => event().key ? event() : last)
I'm not bothered.
nikivi
nikivi2y ago
yea its ok thank you ❤️
deluksic
deluksic2y ago
I did not follow the discussion super closely, but If you want to prevent effects from running on certain signals, use untrack.
Alex Lohr
Alex Lohr2y ago
Or on, which tracks only the reactive arguments and ignores the whole rest. Since he uses grid and snake, but only needs to track event, on was simpler.
Want results from more Discord servers?
Add your server