S
SolidJS2mo ago
Tom

Using createEffect to denormalise for efficiency - good/bad idea?

My question is related to this advice, from the docs:
Effects are meant primarily for side effects that read but don't write to the reactive system: it's best to avoid setting signals in effects, which without care can cause additional rendering or even infinite effect loops. Instead, prefer using createMemo to compute new values that depend on other reactive values, so the reactive system knows what depends on what, and can optimize accordingly.
Say I'm building a spreadsheet like app. There could be many thousands of cells. One can be selected. Let's say each has an ID and there's a central store that has selectedCellID. Each cell can have: selected = createMemo(() => props.cellID == store.selectedCellID) When selectedCellID changes, every one of those memos will run, right? Seems very inefficient. So instead how about store.cells which is contains state for each cell, keyed on the cellID. Now the cell has state = createMemo(() => store.cells[props.cellID]) and in the JSX something like state().isSelected Now I have to keep these selected states in sync, which I could do with createEffect.
createEffect((prev) => {
const {selectedID} = store
batch(() => {
setStore('cells', prev, 'isSelected', false)
setStore('cells', selectedID, 'isSelected', true)
})
return selectedID
})
createEffect((prev) => {
const {selectedID} = store
batch(() => {
setStore('cells', prev, 'isSelected', false)
setStore('cells', selectedID, 'isSelected', true)
})
return selectedID
})
This is creating a dependency of course, and as the docs say, without care these can lead to extra renders and even endless loops. But with care, this seems like a reasonable thing to do. Thoughts? Is this kind of pattern documented somewhere that I missed? Thanks : )
3 Replies
Alex Lohr
Alex Lohr2mo ago
You seem to have missed createSelector, which is for this exact use case.
Tom
Tom2mo ago
Perfect - thanks! Hmm this seems quite limited to a very specific use-case. My question is about the broader concept of using createEffect to denormalise, for efficiency reasons. For example, createSelector looks like it can't support multiple selections. I'll have a look at the source for createSelector to learn how best to do things like this. I stand corrected about the multiple selection - looks like that's possible using the second arg to createSelector Looks like createSelector internals are a bit beyond my understanding, relying on internal things that are not in the docs. I'm going to press ahead see if createSelector will work for my use-case, and avoid the pattern I posted above for now. Maybe it won't be needed.
Alex Lohr
Alex Lohr2mo ago
I find it a bit underdocumented, too. But it is really powerful.
Want results from more Discord servers?
Add your server