S
SolidJS•2y ago
hotshoe

Can a Solid store contain class objects?

Can a Solid store contain class objects? When I implement a simple type like below as a class, reactivity breaks for me when surfacing in a Solid store via a context provider.
// Works
export type ArtistProps = {
id: number;
name: string;
genre: string;
};
... setter({ id: 1, "Kiss", "Rock "})
// Works
export type ArtistProps = {
id: number;
name: string;
genre: string;
};
... setter({ id: 1, "Kiss", "Rock "})
// Doesn't work
export type ArtistProps = {
constructor (readonly id: number, name: string, genre: string) {}
};
... setter(new {1, "Kiss", "Rock"})
// Doesn't work
export type ArtistProps = {
constructor (readonly id: number, name: string, genre: string) {}
};
... setter(new {1, "Kiss", "Rock"})
Do Solid store objects need to be pojos?
10 Replies
Unknown User
Unknown User•2y ago
Message Not Public
Sign In & Join Server To View
REEEEE
REEEEE•2y ago
Classes aren't reactive by default
romanobro
romanobro•2y ago
solid stores do not work with classes, watched this video today actually and its quite good https://youtu.be/HsMAMsaDpzU
Jeman Dev
YouTube
I'll read the docs for you... | SolidJS Stores
In this video, I will be discussing what I learned about Stores from the SolidJS Documentation. #solidjs #frontenddeveloper #frontend Do consider leaving a like and subscribing if you liked the video. Music from #Uppbeat (free for Creators!): https://uppbeat.io/t/noxz/flvx License code: B7KUGCPA1FCXQPWJ
hotshoe
hotshoeOP•2y ago
Thx for the ptr @romanobro , the video certainly makes it clear that classes are not supported, and I re-checked the docs and found Classes are not wrapped, so objects like Date, HTMLElement, RegExp, Map, Set won't be granularly reactive as properties on a store. so, it seems I glossed over this. Too bad not supported 😦 as this is something Svelte handles by default (although, I much prefer Solid's reactivity model overall).
REEEEE
REEEEE•2y ago
You can make the class itself reactive though im not sure how it would work in a store, might be fine If you add, return createMutable(this) to the constructor
hotshoe
hotshoeOP•2y ago
@._rb , Your suggestion works (in a store). Thank you!! The docs discourage usage so I didn't try, but leaves me in no worse shape (from caveat perspective than with Svelte, where everything is 2-way binding) and my use case is special case. Sorry to keep mentioning Svelte, btw, I'm developing my next project using both SK And SS to decide on my metafw of choice going fwd and heavily leaning towards SS -- just wish it was 1.0 then would be easy choice for me, which says a lot about how awesome SS is. Thanks again!
Unknown User
Unknown User•2y ago
Message Not Public
Sign In & Join Server To View
Joe Pea
Joe Pea•2y ago
You can use createStore and createMutable with classes, but createMutable is gonna be a lot easier.
class Thing {
a = 1
b = 2
c = 3

doSomething() {
this.a++
}

constructor() {
return createMutable(this)
}
}

const thing = new Thing()

createEffect(() => {
console.log(thing.a, thing.b, thing.c)
})

thing.doSomething() // logs
thing.b++ // logs
thing.c++ // logs
class Thing {
a = 1
b = 2
c = 3

doSomething() {
this.a++
}

constructor() {
return createMutable(this)
}
}

const thing = new Thing()

createEffect(() => {
console.log(thing.a, thing.b, thing.c)
})

thing.doSomething() // logs
thing.b++ // logs
thing.c++ // logs
Try in Playground: https://playground.solidjs.com/anonymous/19fe511b-71e5-4bb1-9e4d-a6d5995da239
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Joe Pea
Joe Pea•2y ago
If you have decorators, I help make some new class patterns possible with classy-solid https://github.com/lume/classy-solid For example:
@reactive class Thing {
@signal a = 1 // reactive
@signal b = 2 // reactive
c = 3 // not reactive
}

const thing = new Thing()

createEffect(() => {
console.log(thing.a, thing.b)
})

createEffect(() => {
console.log(thing.c) // will not re-run, not a signal
})
@reactive class Thing {
@signal a = 1 // reactive
@signal b = 2 // reactive
c = 3 // not reactive
}

const thing = new Thing()

createEffect(() => {
console.log(thing.a, thing.b)
})

createEffect(() => {
console.log(thing.c) // will not re-run, not a signal
})
GitHub
GitHub - lume/classy-solid: Solid.js reactivity patterns for classe...
Solid.js reactivity patterns for classes, and class components. - GitHub - lume/classy-solid: Solid.js reactivity patterns for classes, and class components.
Joe Pea
Joe Pea•2y ago
For reference, here's a class using createStore:
class Thing {
a = 1
b = 2
c = 3

doSomething() {
this.__setState(state => ({...state, a: this.a + 1}))
}

incB() {
this.__setState(state => ({...state, b: this.b + 1}))
}

incC() {
this.__setState(state => ({...state, c: this.c + 1}))
}

__ = createStore(this)
__state = this.__[0]
__setState = this.__[1]

constructor() {
return this.__state
}
}

const thing = new Thing()

createEffect(() => {
console.log(thing.a, thing.b, thing.c)
})

thing.doSomething() // logs
thing.incB() // logs
thing.incC() // logs
class Thing {
a = 1
b = 2
c = 3

doSomething() {
this.__setState(state => ({...state, a: this.a + 1}))
}

incB() {
this.__setState(state => ({...state, b: this.b + 1}))
}

incC() {
this.__setState(state => ({...state, c: this.c + 1}))
}

__ = createStore(this)
__state = this.__[0]
__setState = this.__[1]

constructor() {
return this.__state
}
}

const thing = new Thing()

createEffect(() => {
console.log(thing.a, thing.b, thing.c)
})

thing.doSomething() // logs
thing.incB() // logs
thing.incC() // logs
createStore is more restrictive, the end user of the class cannot mutate properties directly, but you can expose methods to do so. Playground: https://playground.solidjs.com/anonymous/05e85883-2abb-4e5a-a5f3-5e2977b689b4
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Want results from more Discord servers?
Add your server