我是redux工具包的新手,但是经过长时间的研究,我设法为redux工具包编写了这个配置,以便从我的后端express API获取数据。如果我走对了,有人能给我指路吗?
我应该使用createAsyncThunk还是这个配置也是正确的?
store.js
import { configureStore } from "@reduxjs/toolkit";
import productReducer from "./features/productSlice";
export const store = configureStore({
reducer: {
products: productReducer,
},
});
productSlice.js
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
products: [],
isLoading: false,
error: null,
};
export const productsSlice = createSlice({
name: "products",
initialState,
reducers: {
startLoading: (state) => {
state.isLoading = true;
},
hasError: (state, action) => {
state.error = action.payload;
state.isLoading = false;
},
allProductsSuccess: (state, action) => {
state.products = action.payload;
state.isLoading = false;
},
},
});
export default productsSlice.reducer;
productActions.js
import axios from "axios";
import { productsSlice } from "./productSlice";
const { allProductsSuccess, startLoading, hasError } = productsSlice.actions;
export const fetchProducts = () => async (dispatch) => {
dispatch(startLoading());
try {
const { data } = await axios.get("/api/v1/products");
dispatch(allProductsSuccess(data.products));
} catch (e) {
dispatch(hasError(e?.response?.data?.message));
}
};
Home.js(组件)
const { products, isLoading } = useSelector((state) => state.products);
console.log(products, isLoading)
useEffect(() => {
dispatch(fetchProducts());
}, []);
谢谢!
正确吗?当然,看起来它可以编译和运行,并做你想做的事情。
是推荐的实现吗?不完全是。使用createAsyncThunk
实用程序,您可以减少一些样板文件/重复代码。你可以有效地"合并"。productSlice.js
和productActions.js
文件,因为所有相关操作都可以从productSlice.js
文件导出。createAsyncThunk
生成"pending"/"success" error">
的例子:
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
export const fetchProducts = createAsyncThunk(
"products/fetchProducts",
async (_, thunkAPI) => {
try {
const { data } = await axios.get("/api/v1/products");
return data;
} catch (e) {
return thunkAPI.rejectWithValue(e?.response?.data?.message);
}
}
);
const initialState = {
products: [],
isLoading: false,
error: null,
};
const productsSlice = createSlice({
name: "products",
initialState,
extraReducers: builder => {
builder
.addCase(fetchProducts.pending, (state) => {
state.isLoading = true;
})
.addCase(fetchProducts.fulfilled, (state, action) => {
state.products = action.payload.products;
state.isLoading = false;
})
.addCase(fetchProducts.rejected, (state, action) => {
state.error = action.payload;
state.isLoading = false;
});
},
});
export default productsSlice.reducer;