When to use createEffect

I have a signal that depends on another signal. My todos signal is depended on my user signal. When there is a user, I want to subscribe to the todos collection, and when there isn't I want to unsubscribe. When there is again (login), I want to resubscribe (user could change too). Should I use createEffect for this? I thought you shouldn't set a signal inside a signal though? Here is my code:
export function useTodos() {

const _user = useUser();

const _store = createStore<{
todos: TodoItem[],
loading: boolean
}>({
todos: [],
loading: true
});

const user = _user[0];

const setTodos = _store[1];

setTodos(v => ({ ...v, loading: true }));

if (!user.data) {
setTodos({ loading: false, todos: [] });
return _store[0];
}

const unusbscribe = onSnapshot(

// query realtime todo list
query(
collection(db, 'todos'),
where('uid', '==', user.data.uid),
orderBy('created')
), (q) => {

// get data, map to todo type
const data = snapToData(q);

/**
* Note: Will get triggered 2x on add
* 1 - for optimistic update
* 2 - update real date from server date
*/

// print data in dev mode
if (process.env.NODE_ENV === 'development') {
console.log(data);
}

// add to store
setTodos({ loading: false, todos: data });

});

onCleanup(unusbscribe);

return _store[0];
};
export function useTodos() {

const _user = useUser();

const _store = createStore<{
todos: TodoItem[],
loading: boolean
}>({
todos: [],
loading: true
});

const user = _user[0];

const setTodos = _store[1];

setTodos(v => ({ ...v, loading: true }));

if (!user.data) {
setTodos({ loading: false, todos: [] });
return _store[0];
}

const unusbscribe = onSnapshot(

// query realtime todo list
query(
collection(db, 'todos'),
where('uid', '==', user.data.uid),
orderBy('created')
), (q) => {

// get data, map to todo type
const data = snapToData(q);

/**
* Note: Will get triggered 2x on add
* 1 - for optimistic update
* 2 - update real date from server date
*/

// print data in dev mode
if (process.env.NODE_ENV === 'development') {
console.log(data);
}

// add to store
setTodos({ loading: false, todos: data });

});

onCleanup(unusbscribe);

return _store[0];
};
Thanks, J
5 Replies
peerreynders
peerreynders7mo ago
Perhaps have a look at how solid-firebase handles things. Note the use of createComputed inside useFirestore to handle the subscription. “However, while createMemo functions should be pure (not set any signals), createComputed functions can set signals.” Perhaps that is what you are looking for.
GitHub
GitHub - wobsoriano/solid-firebase: Solid primitives for Firebase v9.
Solid primitives for Firebase v9. Contribute to wobsoriano/solid-firebase development by creating an account on GitHub.
GitHub
solid-firebase/src/hooks/useFirestore.tsx at 8874541124e057d8ca8107...
Solid primitives for Firebase v9. Contribute to wobsoriano/solid-firebase development by creating an account on GitHub.
jdgamble555
jdgamble555OP7mo ago
createComputed is what I was looking for, perfect, thanks!
peerreynders
peerreynders7mo ago
Just keep in mind that createComputed can have some limitations which may or may not apply in your specific situation.
GitHub
signals in For and Index stay in the past if accessed under batch ·...
Describe the bug Conceptually the signals provided by mapArray (index) and indexArray (value) are derived directly from the input source array. So accessing them during batch should have a similar ...
jdgamble555
jdgamble555OP7mo ago
Shouldn't effect my use case, but unsure about more complex cases, either way, looks like it is on the roadmap to be updated...
peerreynders
peerreynders7mo ago
For some background around createComputed
Ryan Carniato
YouTube
Designing Signals 2.0
Signals are not a new technology. The current wave of Signals and fine-grained rendering has existed in the modern form for the past 7 years. As an early adopter/pioneer in this area I want to talk about where things are and how I see them changing in the next few years. We will take a first look at Solid's work in this area and talk about the t...
Want results from more Discord servers?
Add your server