Tom
Tom
SSolidJS
Created by Tom on 7/15/2024 in #support
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 : )
8 replies
SSolidJS
Created by Tom on 5/3/2024 in #support
Style attribute not updating in Safari
I wonder if anyone has run into this. I've got a SplitPane component that I just discovered doesn't work in Safari. It turns out the style attribute is not updating. I've got it down to
<div data-foo={`width: ${width()}`} style={`width: ${width()}`}>
<div data-foo={`width: ${width()}`} style={`width: ${width()}`}>
I can see data-foo changing in the element inspector, but style remains unchanged. It's the same with the object version of style
<div data-foo={`width: ${width()}`} style={{width: width()}}}>
<div data-foo={`width: ${width()}`} style={{width: width()}}}>
Any ideas? Thanks : )
4 replies
SSolidJS
Created by Tom on 10/18/2023 in #support
Combining Solid store with query engine?
My app needs to support a wide range of object queries and I want them to be fast, i.e. indexed. Something like Loki.js would be perfect (and there are a bunch of other options). However I also need my data to be Solid-reactive, like a Solid store. Has anyone had any experience trying to integrate the Solid store and a query engine? Or other ideas for fast and flexible declarative queries? Thanks
2 replies
SSolidJS
Created by Tom on 4/14/2023 in #support
Efficient reactive rebuild of large derived object
A question about how best to use the reactive primitives for (re)building derived state. I don't think a simple createMemo will do the job well here. I have a store with a large number of 'blocks' (just objects), stored as a large object with id/block pairs, e.g. store.blocks[someID].name I want to build a grouped and sorted "index" of the blocks, e.g an array of 'sections' that groups the blocks by type e.g.
type Sections = {
type: string // from block.type
blocks: Block[] // all blocks with the given block.type, sorted by block.name
}[]
type Sections = {
type: string // from block.type
blocks: Block[] // all blocks with the given block.type, sorted by block.name
}[]
My issue is that a naive implementation using createMemo would end up rebuilding the entire thing every time a change is made to a .type or a .name, or when a block is created/deleted. I am thinking I can probably do something with multiple dependent memos, but before getting into it I thought I'd ask what others have done. Seems like a not uncommon situation. Thanks!
27 replies
SSolidJS
Created by Tom on 2/7/2023 in #support
Router and createRoot
I recently upgraded my app from the old solid-app-router to @solidjs/router. It looks like, where I used to be able to use regular <a> tags and have them handled client-side by the router, I now have to use the <A> component. Is that expected? This has lead to a problem with a component that's created outside of the normal render hierarchy using createRoot (necessary because t's a ProseMirror node-view). Links in that component are giving me an exception with the message Make sure your app is wrapped in a <Router /> Any advice on fixing this? Thanks.
4 replies
SSolidJS
Created by Tom on 1/10/2023 in #support
solid-router nested routes - access child params from parent component
It seems like a parent component can't access the full set of params - it can't see params for child routes. Is that right? I get the logic but I have a classic master/detail view, list on the left, with a selected item showing up on the right. In the list I need to be able to detect which item is active, which depends on the nested route param which is not available. My routes:
<Route path='/:bookID' component={BookView}>
<Route path='/' />
<Route path='/blocks/:blockID' component={BlockEditor}/>
</Route>
<Route path='/:bookID' component={BookView}>
<Route path='/' />
<Route path='/blocks/:blockID' component={BlockEditor}/>
</Route>
It seems params.blockID is not available from BookView. I've tried
<Route path='/:bookID'>
<Route path='/' component={BookView} />
<Route path='/blocks/:blockID' component={BookView}/>
</Route>
<Route path='/:bookID'>
<Route path='/' component={BookView} />
<Route path='/blocks/:blockID' component={BookView}/>
</Route>
and replacing <Outlet> with a conditional call of <BlockEditor/>, but then I get a re-init of BookView, which I really want to avoid.
1 replies