How to trigger focus and scroll across the app?

What is the best way to trigger DOM element related reactions across the app? By across I mean for example by keyboard, related to a different component, etc. In practice, there is a global store, where you want to have a function focus() or scrollToBottom() etc. My current idea is to have a large, random integer in a variable in the store, and in the component rendering the DOM element I just put a dummy createEffect() with this integer and a scroll/focus effect. I guess the alternative is to save the ref into the store, but I think it's very bug prone for all the re-renders. I need to carefully remove it on each cleanup and add it back on each onMount. If you did this in a production app, how did you do it?
7 Replies
zulu
zulu5d ago
who changes the random integer
hyperknot
hyperknotOP5d ago
maybe a handleClick or similar triggers a store.setState('randomInt', Math.random()...)
zulu
zulu5d ago
ok, first you don't need random numbers. you can use the equals of the signal, then you can set it to the same value and it will still trigger. docs are broken for me https://docs.solidjs.com/reference/basic-reactivity/create-signal
createSignal - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
zulu
zulu5d ago
it is the 2nd argument {equals:false} you can try subscribing using the effect on the signal, or you can look into events if it make sense to your use case
hyperknot
hyperknotOP5d ago
but what is the signal then? it needs to be something, a number, a boolean, something for subscribing, do you mean createEffect()?
zulu
zulu5d ago
yes you can use the createEffect to then apply a focus on the html Element
function createTrigger(){
let [t, setT] = createSignal(0, {equals:false});
return [t, ()=>setT(0)];
}

let [signal,trigger] = createTrigger()

createEffect(()=>{
signal()
// do something
});

trigger()
function createTrigger(){
let [t, setT] = createSignal(0, {equals:false});
return [t, ()=>setT(0)];
}

let [signal,trigger] = createTrigger()

createEffect(()=>{
signal()
// do something
});

trigger()
peerreynders
peerreynders5d ago
I'm not sure that your question is DOM specific. The core issue seems to be “how do two totally unrelated components communicate” (which could mean one component happens to know that scrollToBottom has to happen which a completely different one has the facility to perform). These types of problems are solved via context; Example: The NoteEdit component performs new, update, delete operations on a particular note. https://github.com/peerreynders/solid-start-notes-basic/blob/f13872d001dc1680f84330337ac61c0fbe1db1e3/src/components/note-edit.tsx#L64 The BriefList component gives special treatment to the last new or updated note on the list. https://github.com/peerreynders/solid-start-notes-basic/blob/f13872d001dc1680f84330337ac61c0fbe1db1e3/src/components/brief-list.tsx#L136 Other than that both, components are entirely unrelated. A signal inside a context accepts the LastEdit via the sendLastEdit setter and broadcasts it via the lastEdit accessor. https://github.com/peerreynders/solid-start-notes-basic/blob/f13872d001dc1680f84330337ac61c0fbe1db1e3/src/components/app-context.tsx#L18-L20 NoteEdit produces via sendLastEdit and BriefList consumes via lastEdit— otherwise those two are completely unaware of one another.
GitHub
solid-start-notes-basic/src/components/note-edit.tsx at f13872d001d...
Basic client rendered notes app using SolidStart beta - peerreynders/solid-start-notes-basic
GitHub
solid-start-notes-basic/src/components/app-context.tsx at f13872d00...
Basic client rendered notes app using SolidStart beta - peerreynders/solid-start-notes-basic
GitHub
solid-start-notes-basic/src/components/brief-list.tsx at f13872d001...
Basic client rendered notes app using SolidStart beta - peerreynders/solid-start-notes-basic

Did you find this page helpful?