2

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.

hotcakedev
  • 2,194
  • 1
  • 25
  • 47
Ahmad
  • 12,336
  • 6
  • 48
  • 88

1 Answers1

0

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;
}
Ahmad
  • 12,336
  • 6
  • 48
  • 88