'how do I make granular signals that works for properties of a whole pure class
I have a class that keeps input events and lets me query the state.
class Input {
btn() { return this._btn }
_release() { this._btn = -1 }
_press() { this._btn = 0 }
listen() {
document.addEventListener('keydown', e => this._press())
document.addEventListener('keyup', e => this._release())
}
update() {
if (this._btn >= 0) this._btn++
}
}
I use this class like this:
let input = new Input()
input.listen()
function update_every_frame() {
input.update()
}
function check_for_input() {
if (input.btn() > 0) {
console.log('here')
}
}
So using solid style coding I want to make a signal that changes whenever an input btn is pressed:
let [input, setInput] = createSignal(new Input(), { equals: false })
function update_every_frame() {
setInput(input => { input.update(); return input })
}
const check_for_input = () => { return input().btn() }
Now check_for_input is a reactive property that returns the button presses. Except this property up
dates every frame because I call input.update every frame.
I don't want granular signals at the data level, where I pollute the pure data class with signals. Be cause I want to make a data class and test it independent of the library.
So how do I make granular signals that works for properties of a whole pure class.
Edit
Also for example how do I create signals or memo's for an array, or a getter property on a class so the signals are updated accordingly when the class updates it's properties:
class Test {
array: Array
a: number = 0
get computed(): {
return this.a < 4 ? 1 : 0
}
update() {
this.a = 10
}
}
let [instance, setInstance] = createSignal(new Test(), { equals: false })
let arraySignal = createMemo(() => instance().array)
let computedSignal = createMemo(() =>
instance.computed)
How does computedSignal update on this method call:
setInstance(instance => instance.update())
Solution 1:[1]
One way you can do it is like this:
import {createMutable} from 'solid-js/store'
import {createEffect} from 'solid-js'
class Foo {
// any properties here
whatever = 123
constructor() {
return createMutable(this)
}
}
const f = new Foo
createEffect(() => console.log(f.whatever))
f.whatever++ // reactive
or to keep the class really pure:
import {createMutable} from 'solid-js/store'
import {createEffect} from 'solid-js'
class Foo {
// any properties here
whatever = 123
}
const f = createMutable(new Foo)
createEffect(() => console.log(f.whatever))
f.whatever++ // reactive
You said you don't want to make signal for every property, but with classy-solid you can do it in a way that still feels like writing a regular class:
import {reactive, signal} from 'classy-solid'
@reactive
class Foo {
@signal whatever = 123
}
const f = new Foo
createEffect(() => console.log(f.whatever))
f.whatever++ // reactive
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | trusktr |
