import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import {
createUserWithEmailAndPassword,
sendEmailVerification,
} from "firebase/auth";
import { auth } from "../../config/firebase";
import _ from "lodash";
import { db } from "../../config/firebase";
import {
collection,
doc,
addDoc,
getDoc,
query,
getDocs,
QuerySnapshot,
where,
orderBy,
} from "firebase/firestore";
export const firebase_GetProgramDetails = createAsyncThunk(
"programDetailsSlice/firebase_GetProgramDetails",
async (programID, ThunkAPI) => {
const state = ThunkAPI.getState().programDetails;
ThunkAPI.dispatch(pushProgramDetails());
try {
const querySnapshotDays = await getDocs(
query(
collection(db, "programs", programID, "Days"),
orderBy("dayNumber", "asc")
)
);
querySnapshotDays.forEach(async (doc) => {
const exercises = [];
const querySnapshotExercises = await getDocs(
query(
collection(db, "programs", programID, "Days", doc.id, "exercises"),
orderBy("order", "asc")
)
);
querySnapshotExercises.forEach(async (exe) => {
exercises = [];
const exercise = exe.data()["exercise"];
const exeData = await getDoc(exercise);
const exeName = await exeData.data()["exerciseName"];
exercises.push({
...exe.data(),
exerciseName: exeName,
});
});
console.log(querySnapshotExercises.docs);
ThunkAPI.dispatch(
pushProgramDetails({ ...doc.data(), exercises: exercises })
);
});
return true;
} catch (error) {
return ThunkAPI.rejectWithValue(error.message);
}
}
);
export const programDetailsSlice = createSlice({
name: "programDetails",
initialState: {
status: "idle",
programDetails: [],
msg: "",
},
reducers: {
reset: (state, action) => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.status = "idle";
state.programDetails = [];
state.msg = "";
},
pushProgramDetails: (state, action) => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.programDetails = action.payload;
},
},
extraReducers(builder) {
builder
.addCase(firebase_GetProgramDetails.pending, (state, action) => {
state.status = "loading";
state.msg = "";
})
.addCase(firebase_GetProgramDetails.fulfilled, (state, action) => {
state.status = "succeeded";
})
.addCase(firebase_GetProgramDetails.rejected, (state, action) => {
state.status = "failed";
state.msg = action.payload;
state.programDetails = [];
});
},
});
// Action creators are generated for each case reducer function
export const { reset, pushProgramDetails } = programDetailsSlice.actions;
export default programDetailsSlice.reducer;
字符串
我有嵌套集合。因此,对于一个程序,我得到的日子,每一天,我得到的演习。我把所有这些都放到一个对象数组中。如果我把它传递给要设置的状态,我会一直得到没有可扩展的错误,我认为这是因为它是正在传递的软拷贝。
在第一次运行并设置状态后,第二次运行将引发错误。
我试过硬拷贝,它一直在拷贝一个空数组。有没有更简单的方法?
我只是想把所有的东西都放进一个对象数组“数组按天数排序”,然后把它放到状态中显示。
1条答案
按热度按时间tag5nh1u1#
我很抱歉没有把我的问题解释清楚。因此,在从firebase获取查询后,我运行了foreach do get子集合。问题是我得到了这些查询的结果,我把它推到一个数组中并返回。但是React + Redux在严格模式下运行两次,foreach不是异步的,临时数组导致错误,因为它再次被访问,所以不可扩展。它只需要我把它改为for循环和await。这种方法也不是有效的。最后,我提前查询了集合,然后循环遍历它。