To simplify the example I'll use todos.
const [todos, setTodos] = createStore([])
let unsubscribe;
onMount(() => {
unsubscribe = onSnapshot(collection("pathToTodos"), snapshot => {
if(!todos.length) {
setTodos(todosFromSnapshot)
} else {
const todoToUpdate = todos.filter((todo, i) => todo.propToFilterOn !== todosFromSnapshot[i].propToFilterOn)[0]
setTodos((todo) => todo.id === todoToUpdate.id, todoToUpdate)
}
})
})
onCleanup(() => unsubscribe && unsubscribe())
return (
<Show when={todos.length}>
<For each={todos}>
{(todo, index) => {
<Todo todo={todo} index={index()} />
}}
</For>
</Show>
)
I'm trying to listen to changes in Firestore and update the Todo that has changed completely, not just one property but for the sake of this example when the button is clicked it just updates the Todo in Firestore which then triggers the onSnapshot callback, the store is not updated in the onClick handler. It works fine until I use two devices and try to update them close together. It appears like the list of todos "re-renders" at the same time as the second "click" and so the "click" isn't registered but instead the focus/hover state appears and the button must be clicked again to fire the function.
This was happening to me in React even when using Memo, useCallback. I set the background colour to change on every re-render and the component definitely wasn't re-rendering but I still had this glitch happening when the snapshot is triggered. I thought that because in React you use .map to create a new array that this was causing the issue.
I thought with Solid's createStore that every object in the array is its own signal, so updating one object in the store would not affect other objects in the array.
Not sure how to add video or gifs here but added a screen record to better show it https://i.makeagif.com/media/6-01-2023/-nTwSu.gif
Any advice? Only one todo is ever updated at one time and I only want that specific one to re-render.