提问人:jonteal 提问时间:11/8/2023 更新时间:11/8/2023 访问量:34
如何使用 Redux Toolkit 和 Apollo 的 useQuery 数据设置 initialState?
How to set initialState using Redux Toolkit with data using Apollo's useQuery?
问:
我正在尝试在 redux 工具包切片中调用 useQuery 钩子(功能组件之外不允许的东西)。这是否可行,也许使用 createAsyncThunk 或类似方法?我的应用程序是使用 MERN 堆栈构建的,所以我的数据库是 MongoDB,我使用 Graphql 来获取数据。(在此示例中,我忽略了 reducer,因为我只专注于获取数据并将其设置为初始状态。
import { useQuery } from "@apollo/client";
import { createSlice } from "@reduxjs/toolkit";
import { GET_USER_SETTINGS } from "../graphql/queries/settingsQueries";
const { loading, error, data } = useQuery(GET_USER_SETTINGS);
const { gridView } = data.settings;
const initialState = {
gridView,
};
const settingsSlice = createSlice({
name: "settings",
initialState,
reducers: {
setGridViewOff(state) {
state.gridView = false;
},
setGridViewOn(state) {
state.gridView = true;
},
},
});
export const { setGridViewOff, setGridViewOn } = settingsSlice.actions;
export default settingsSlice.reducer;
答:
0赞
Drew Reese
11/8/2023
#1
你是对的,你不能从 Redux slice 代码调用。我在这里的建议是使用一些“未定义”的初始状态,并使用钩子来“初始化”值。useQuery
gridView
useEffect
gridView
类似于以下示例的内容:Something similar to the following example:
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
gridView: undefined,
};
const settingsSlice = createSlice({
name: "settings",
initialState,
reducers: {
initializeGridView: (state, action) => {
state.gridView = action.payload;
},
setGridViewOff(state) {
state.gridView = false;
},
setGridViewOn(state) {
state.gridView = true;
},
},
});
export const {
initializeGridView,
setGridViewOff,
setGridViewOn
} = settingsSlice.actions;
export default settingsSlice.reducer;
import { useEffect } from "react";
import { useQuery } from "@apollo/client";
import { useDispatch } from "react-redux";
import { initializeGridView } from "../path/to/settings.slice";
import { GET_USER_SETTINGS } from "../graphql/queries/settingsQueries";
const useInitializeGridView = () => {
const dispatch = useDispatch();
const { loading, data } = useQuery(GET_USER_SETTINGS);
useEffect(() => {
if (!loading) {
const gridView = !!data?.settings?.gridView;
dispatch(initializeGridView(gridView));
}
}, [loading, data]);
};
在应用程序中靠近 Redux 所在范围的根附近的某个位置调用,例如在 ReactTree 的 Redux 组件下。任何依赖于该值的 UI 都应首先检查是否定义了该值,然后使用定义的 true/false 值。useInitializeGridView
Provider
state.settings.gridView
-1赞
BugHunter
11/8/2023
#2
您可以通过创建一个 Redux Thunk 操作来获取数据并设置初始状态,然后从您的组件调度 Redux Thunk 操作来处理这个问题。
例
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { useQuery } from "@apollo/client";
import { GET_USER_SETTINGS } from "../graphql/queries/settingsQueries";
export const fetchUserSettings = createAsyncThunk("settings/fetchUserSettings", async (_, { dispatch }) => {
try {
const { data } = await useQuery(GET_USER_SETTINGS);
const gridView = data.settings.gridView;
return { gridView };
} catch (error) {
throw error;
}
});
const initialState = {
gridView: null,
};
const settingsSlice = createSlice({
name: "settings",
initialState,
reducers: {
setGridViewOff(state) {
state.gridView = false;
},
setGridViewOn(state) {
state.gridView = true;
},
},
extraReducers: (builder) => {
builder.addCase(fetchUserSettings.fulfilled, (state, action) => {
state.gridView = action.payload.gridView;
});
},
});
export const { setGridViewOff, setGridViewOn } = settingsSlice.actions;
export default settingsSlice.reducer;
评论