redux/reducer/cartReducer.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { CartReducerInitialState } from "../../types/reducer-types";
import { CartItem, ShippingInfo } from "../../types/types";
const initialState: CartReducerInitialState = {
loading: false,
cartItems: [],
subtotal: 0,
tax: 0,
shippingCharges: 0,
discount: 0,
total: 0,
shippingInfo: {
address: "",
city: "",
state: "",
country: "",
pinCode: "",
},
};
export const cartReducer = createSlice({
name: "cartReducer",
initialState,
reducers: {
addToCart: (state, action: PayloadAction<CartItem>) => {
state.loading = true;
const index = state.cartItems.findIndex(
(i) => i.productId === action.payload.productId
);
if (index !== -1) state.cartItems[index] = action.payload;
else state.cartItems.push(action.payload);
state.loading = false;
},
removeCartItem: (state, action: PayloadAction<string>) => {
state.loading = true;
state.cartItems = state.cartItems.filter(
(i) => i.productId !== action.payload
);
state.loading = false;
}
},
});
export const {
addToCart,
removeCartItem
} = cartReducer.actions;
redux/store.ts
import { configureStore } from "@reduxjs/toolkit";
import { userAPI } from "./api/userAPI";
import { userReducer } from "./reducer/userReducer";
import { productAPI } from "./api/productAPI";
import { cartReducer } from "./reducer/cartReducer";
import { persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import {combineReducers} from "@reduxjs/toolkit";
export const server = import.meta.env.VITE_SERVER;
const reducers = combineReducers({
[userAPI.reducerPath]: userAPI.reducer,
[productAPI.reducerPath]: productAPI.reducer,
[userReducer.name]: userReducer.reducer,
[cartReducer.name]: cartReducer.reducer
});
const persistConfig = {
key: 'root',
storage,
whitelist: ["cartReducer"]
};
const persistedReducer = persistReducer(persistConfig, reducers)
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat([
userAPI.middleware,
productAPI.middleware
]),
});
export type RootState = ReturnType<typeof store.getState>
页面/Home.tsx
const { cartItems, subtotal, tax, total, shippingCharges, discount } = useSelector((state: { cartReducer: CartReducerInitialState }) => state.cartReducer)
const { data, isError, isLoading } = useLatestProductsQuery("")
// console.log(data)
console.log(cartItems)
const dispatch = useDispatch()
const addToCartHandler = (cartItem: CartItem) => {
if(cartItem.stock < 1) return toast.error("Out of Stock")
dispatch(addToCart(cartItem))
toast.success("Item added to cart")
}
{
data?.products.map((i) => (
<ProductCard key={i._id} productId={i._id} name={i.name} price={i.price}
category={i.category} stock={i.stock} handler={addToCartHandler} photo={i.photo} />
))
}
组件/ProductCard.tsx
type ProductProps = {
productId: string
photo: string
name: string
category: string
price: number
stock: number
handler: (cartItem: CartItem) => string | undefined
}
const ProductCard = ({
productId,
photo,
name,
category,
price,
stock,
handler
}: ProductProps) => {
return (
<div className="product-card">
<h3 className="category">{category.toUpperCase()}</h3>
<img src={`${server}/${photo}`} alt={name} />
<p>{name}</p>
<span>HK$ {price}</span>
<div>
<button onClick={() => handler({
productId,
price,
name,
category,
photo,
stock,
quantity: 1
})}>
<FaPlus />
</button>
</div>
</div>
)
}
类型/types.ts
export type CartItem = {
productId: string
photo: string
name: string
category: string
price: number
quantity: number
stock: number
}
在这个项目中,我想维护当用户单击添加按钮时已添加的购物车的状态。即使我使用减速器正确注册了商店,
cartReducer
也无法维护单击按钮后添加的项目。到目前为止,我尝试添加redux-persist
,但是当我点击添加按钮并刷新时,状态仍然无法保持。我按照 redux 中的文档进行了多次尝试,但仍然卡在这里,所以任何人都可以提供帮助来解决问题吗?
您似乎已经实现了大约一半的持久性设置。缺少的是创建一个
persistor
对象以及可能的 PersistGate
。
import { configureStore, combineReducers } from "@reduxjs/toolkit";
import {
persistStore, // <-- add import
persistReducer
} from 'redux-persist'
import storage from 'redux-persist/lib/storage';
import { userAPI } from "./api/userAPI";
import { userReducer } from "./reducer/userReducer";
import { productAPI } from "./api/productAPI";
import { cartReducer } from "./reducer/cartReducer";
export const server = import.meta.env.VITE_SERVER;
const reducers = combineReducers({
[userAPI.reducerPath]: userAPI.reducer,
[productAPI.reducerPath]: productAPI.reducer,
[userReducer.name]: userReducer.reducer,
[cartReducer.name]: cartReducer.reducer
});
const persistConfig = {
key: 'root',
storage,
whitelist: [cartReducer.name]
};
const persistedReducer = persistReducer(persistConfig, reducers)
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat([
userAPI.middleware,
productAPI.middleware
]),
});
export const persistor = persistStore(store); // <-- export persistor
export type RootState = ReturnType<typeof store.getState>
然后在 UI 中确保您使用 Redux
PersistGate
组件下的 Provider
包装应用程序。
示例:
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './path/to/redux/store';
const AppRoot = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
};