【问题标题】:Redux Toolkit and AxiosRedux 工具包和 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:无法在已撤销的代理上执行“获取”

有没有办法解决这个问题?

【问题讨论】:

    标签: javascript reactjs redux axios toolkit


    【解决方案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 的魔力的一部分 ;)
    猜你喜欢
    • 2021-08-06
    • 2021-11-06
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2021-08-08
    • 2021-01-05
    相关资源
    最近更新 更多