Redux Toolkit:我可以将 createAsycThunk 与 Firebase 侦听器函数(例如 firestore.collection.onSnapshot)一起使用吗

ste*_*kim 6 firebase redux google-cloud-firestore redux-toolkit

有没有办法将createAsyncThunk与 Firebase 侦听器一起使用,例如firestore.collection.onSnapshot

它可能不起作用,因为 onSnapshot 的工作方式(它是一个侦听器,每次 firestore 更新时都会接收数据并触发回调,并返回一个取消订阅侦听器的函数)。我尝试实现 createAsyncThunk 但无法弄清楚。

这是我当前的 thunk 实现,它确实有效:

const listenerUnsubscribeList = [];
export function fetchProjects() {
  return dispatch => {
    dispatch(fetchProjectsPending());
    const unsubscribe = firestore
      .collection('projects')
      .onSnapshot(
        snapshot => { dispatch(fetchProjectsFulfilled(snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })))) },
        error => { dispatch(fetchProjectsError(error)) },
      );
    listenerUnsubscribeList.push(unsubscribe);
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我对 createAsyncThunk 的尝试,但不起作用。我得到了database/fetchProjects/pendingdatabase/fetchProjects/fulfilled但有效负载是undefined

const listenerUnsubscribeList = [];
export const fetchProjects = createAsyncThunk(
  'database/fetchProjects',
  async (_, thunkAPI) => {
    const unsubscribe = await firestore
      .collection('projects')
      .onSnapshot(
        snapshot => { return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })) },
        error => { return error },
      );
    listenerUnsubscribeList.push(unsubscribe);
  }
);
Run Code Online (Sandbox Code Playgroud)

Wal*_*cke 1

我尝试让它工作createAsyncThunk但没能解决它。

我不知道我的方法是否正确,但我只是创建了一个自定义thunk来根据需要重新触发任何操作。我创建一个loading//fulfilled操作error来相应地处理数据。

// Action.js

/*
  listenToInboxInDb is a firebase listener that will re-fire with fresh data.
  See how I am returning unsubscribe to be able to call unsubscribe 
  when my component unmounts
*/

export const getConnectionRequests = () => {
  return (dispatch) => {
    dispatch(fetchConnectionsRequestsLoading())

    const unsubscribe = listenToInboxInDb(([data, error]) => {
      if (data) {
        dispatch(fetchConnectionsRequestFullfilled(data))
      }

      if (error) {
        dispatch(fetchConnectionsRequestRejected(error))
      }
    })

    return unsubscribe
  }
}
Run Code Online (Sandbox Code Playgroud)
// Reducer.js

const connectionsSlice = createSlice({
  name: "connections",
  initialState: INITIAL_STATE,
  reducers: {
    // ...other reducers

    fetchConnectionsRequestsLoading(state) {
      state.connectionRequestsStatus = REQUEST_STATUS.loading
    },
    fetchConnectionsRequestFullfilled(state, action) {
      state.error = null
      state.data.connectionRequests = action.payload
      state.connectionRequestsStatus = REQUEST_STATUS.succeeded
    },
    fetchConnectionsRequestRejected(state, action) {
      state.error = action.error
      state.connectionRequestsStatus = REQUEST_STATUS.failed
    },
  },
})
Run Code Online (Sandbox Code Playgroud)