目前正在学习如何将 RTK 与 typescript 结合使用。我有 2 个切片,其中一个是我使用 RTK 查询制作的以获取数据(称为apiSlice.ts
),另一个使用 createSlice 来处理我的待办事项应用程序的同步状态更改(称为snackbarSlice.ts
).
我在 SnackbarSlice 中设置的初始状态根本没有保存到商店,在 chrome redux devtools 和 console.logged 中也进行了检查,但它们确实包含 apiSlice 相关信息,只需注意 Snackbar 相关信息即可。知道我可能做错了什么吗?我觉得我已经开始做这件事太久了。
在控制台中,我收到错误: Uncaught TypeError: Cannot read properties of undefined (reading 'isOpen') on CustomSnackbar (CustomSnackbar.tsx:12:1) ,鉴于状态对象没有 isOpen 键,这是有意义的。
下面是我的代码:
snackbarSlice.ts
:
import { RootState } from "../store";
type SnackbarState = {
content: string;
isOpen: boolean;
};
const initialState: SnackbarState = {
content: "",
isOpen: false,
};
export const snackbarSlice = createSlice({
name: "snackbar",
initialState,
reducers: {
openSnackbar: (state, action: PayloadAction<string>) => {
state.isOpen = true;
state.content = action.payload;
},
closeSnackbar: (state) => {
state.isOpen = false;
state.content = "";
},
},
});
export const { openSnackbar, closeSnackbar } = snackbarSlice.actions;
export const selectIsSnackbarOpen = (state: RootState): boolean =>
state.snackbar.isOpen;
export const selectSnackbarContent = (state: RootState): string =>
state.snackbar.content;
export default snackbarSlice.reducer;
rootReducer.ts
import { apiSlice } from "./features/apiSlice";
import snackbarReducer from "./features/snackbarSlice";
const rootReducer = combineReducers({
snackbar: snackbarReducer,
[apiSlice.reducerPath]: apiSlice.reducer,
});
export default rootReducer;
store.ts
import { apiSlice } from "./features/apiSlice";
import rootReducer from "./rootReducer";
export const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(apiSlice.middleware),
});
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
索引.tsx
import { App } from "./components/app/App";
import React from "react";
import { ApiProvider } from "@reduxjs/toolkit/dist/query/react";
import { apiSlice } from "./store/features/apiSlice";
import { Provider } from "react-redux";
import { store } from "./store/store";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<Provider store={store}>
<ApiProvider api={apiSlice}>
<App />
</ApiProvider>
</Provider>
</React.StrictMode>
);
自定义Snackbar.tsx
import { useAppDispatch, useAppSelector } from "../../hooks/reduxHooks";
import {
closeSnackbar,
selectIsSnackbarOpen,
selectSnackbarContent,
} from "../../store/features/snackbarSlice";
import styles from "./CustomSnackbar.module.css";
export const CustomSnackbar = (): ReactElement => {
const dispatch = useAppDispatch();
const isSnackbarOpen = useAppSelector(selectIsSnackbarOpen);
const snackbarContent = useAppSelector(selectSnackbarContent);
const handleClose = (): void => {
dispatch(closeSnackbar());
};
return (
<div>
{isSnackbarOpen && (
<div className={styles["snackbar"]}>
<div>
<span className={styles["snackbar-btn"]} onClick={handleClose}>
x
</span>
{snackbarContent}
</div>
</div>
)}
</div>
);
};
在任何需要打开小吃栏的文件中,我运行以下代码:ispatch(openSnackbar("An error occurred while deleting task."));
对我可能会错过什么有什么想法吗?