I have a redux toolkit slice file with the following code
import { createSlice } from "@reduxjs/toolkit";
const slice = createSlice({
name: "users",
initialState: [],
reducers: {
ADD: (state, {payload}) => { state.push(payload); },
DELETE: (state, {payload}) => { state = state.filter(u => u.id !== payload); }
}
});
export const { ADD, DELETE } = slice.actions;
export default slice.reducer;
I am trying to setup a firestore onSnapshot
listener and invoke the ADD, DELETE actions when they happen real-time. Here is how I am currently doing it:
...
...
...
export const { ADD, DELETE } = slice.actions;
export const listen = (dispatch /* passed in from component useDispatch() */) => {
const unsub = onSnapshot(collection(db, "users"), (snapshot)=>{
snapshot.docChanges().forEach(change => {
if(change.type === "added") {
dispatch(ADD( { ...doc.data(), id: doc.id }));
} else if (change.type === "removed") {
dispatch(DELETE(doc.id));
}
});
});
return unsub;
}
The only issue, is I have to pass in dispatch
from a certain component when I setup this function in useEffect.
How can I call the function above, without needing to pass in the dispatch reference?
PS: I already know that createAsyncThunk
has a built-in reference to dispatch, but onSnapshot
is not called asynchronously. It is not applicable to it.
I found out how to do it using a normal function that returns a function. Redux will automatically pass a reference to dispatch if the function returns a function.
...
...
...
export const { ADD, DELETE } = slice.actions;
export const listen = () => dispatch => {
const unsub = onSnapshot(collection(db, "users"), (snapshot)=>{
snapshot.docChanges().forEach(change => {
if(change.type === "added") {
dispatch(ADD( { ...doc.data(), id: doc.id }));
} else if (change.type === "removed") {
dispatch(DELETE(doc.id));
}
});
});
return unsub;
}