Redux 工具包和 Axios
Posted
技术标签:
【中文标题】Redux 工具包和 Axios【英文标题】:Redux Toolkit and Axios 【发布时间】:2020-05-29 21:50:29 【问题描述】:我正在使用 Redux Toolkit 通过 Axios 连接到 API。 我正在使用以下代码:
const products = createSlice(
name: "products",
initialState:
products[]
,
reducers:
reducer2: state =>
axios
.get('myurl')
.then(response =>
//console.log(response.data.products);
state.products.concat(response.data.products);
)
);
axios 正在连接到 API,因为要打印到控制台的注释行正在向我显示数据。但是, state.products.concat(response.data.products);抛出以下错误:
TypeError:无法在已撤销的代理上执行“获取”
有没有办法解决这个问题?
【问题讨论】:
【参考方案1】:我更愿意将createAsyncThunk
用于API 数据和extraReducers
假设这个页面名称是productSlice.js
import createSlice,createSelector,PayloadAction,createAsyncThunk, from "@reduxjs/toolkit";
export const fetchProducts = createAsyncThunk(
"products/fetchProducts", async (_, thunkAPI) =>
try
//const response = await fetch(`url`); //where you want to fetch data
//Your Axios code part.
const response = await axios.get(`url`);//where you want to fetch data
return await response.json();
catch (error)
return thunkAPI.rejectWithValue( error: error.message );
);
const productsSlice = createSlice(
name: "products",
initialState:
products: [],
loading: "idle",
error: "",
,
reducers: ,
extraReducers: (builder) =>
builder.addCase(fetchProducts.pending, (state) =>
state. products = [];
state.loading = "loading";
);
builder.addCase(
fetchProducts.fulfilled, (state, payload ) =>
state. products = payload;
state.loading = "loaded";
);
builder.addCase(
fetchProducts.rejected,(state, action) =>
state.loading = "error";
state.error = action.error.message;
);
);
export const selectProducts = createSelector(
(state) => (
products: state.products,
loading: state.products.loading,
), (state) => state
);
export default productsSlice;
在您的store.js
中添加productsSlice: productsSlice.reducer
到店外减速器。
然后在组件中使用添加这些代码......我也更喜欢使用钩子
import useSelector, useDispatch from "react-redux";
import
fetchProducts,
selectProducts,
from "path/productSlice.js";
然后最后一部分像这样在你的主管内部调用这些方法
const dispatch = useDispatch();
const products = useSelector(selectProducts);
React.useEffect(() =>
dispatch(fetchProducts());
, [dispatch]);
最后,您可以在组件中以products
的身份访问数据。
【讨论】:
我对这个答案表示赞赏,并强烈建议任何使用 react-redux 的人完整阅读这个“redux essentials”文档,并非常虔诚地遵循这些模式,它们太棒了! redux.js.org/tutorials/essentials/part-5-async-logic 这个答案非常详细。我没见过比这更好的了。这非常重要,尤其是 createAsyncThunk。谢谢【参考方案2】:这是因为你的 reducer 函数不是纯函数,它不应该有任何异步调用。
这样的东西应该可以工作。它将解决您遇到的错误
const products = createSlice(
name: "products",
initialState:
products: []
,
reducers:
reducer2: (state, payload ) =>
return products: [...state.products, ...payload]
)
);
而且api应该在外面调用
const fetchProducts = () =>
axios.get('myurl')
.then(response =>
//console.log(response.data.products);
store.dispatch(products.actions.reducer2(response.data.products))
)
;
PS:上面的代码没试过运行,可能需要根据需要进行修改。
【讨论】:
FWIK,return products: [...state.products, ...payload]
可以缩写为 state.products.push(payload)
甚至(不确定)state.products = payload
。这是 Redux Toolkit 的魔力的一部分 ;)以上是关于Redux 工具包和 Axios的主要内容,如果未能解决你的问题,请参考以下文章
如何将 axios 添加到 react-redux-universal-hot-example 入门套件?