反应useContext()返回未定义

时间:2020-07-11 19:07:37

标签: javascript reactjs

我为上下文提供程序提供了此代码,我将其包装在组件中,但是当我尝试在使用useProductState或useProductDispatch的孩子中使用它时,它仍返回未定义(抛出err);

import React from "react";

import productsReducer from "./productsReducer";

const ProductsStateContext = React.createContext();
const ProductsDispatchContext = React.createContext();

const initialState = {
  restaurantTitle: "",
  restaurantId: "VljSa5Eakepw9QkTAUOW",
  productsCollection: "",
  categories: [],
  defaultCategory: "",
  isLoading: true,
};

function ProductsProvider({ children }) {
  const [state, dispatch] = React.useReducer(productsReducer, initialState);

  return (
    <ProductsStateContext.Provider value={state}>
      <ProductsDispatchContext.Provider value={dispatch}>
        {children}
      </ProductsDispatchContext.Provider>
    </ProductsStateContext.Provider>
  );
}

function useProductsState() {
  const context = React.useContext(ProductsStateContext);
  if (context === undefined) {
    throw new Error("useProductsState must be used within a ProductsProvider");
  }
  return context;
}
function useProductsDispatch() {
  const context = React.useContext(ProductsDispatchContext);
  if (context === undefined) {
    throw new Error(
      "useProductsDispatch must be used within a ProductsProvider"
    );
  }
  return context;
}

export { ProductsProvider, useProductsState, useProductsDispatch };

有人可以解释它是如何工作的,我正在尝试访问状态并将其分派到.f的子元素中。

更新:

这是我的减速器的动作

case "FETCH_RESTAURANT_DATA": {
      return fetchRestaurantData(state, action.payload);
    }

功能主体如下:

const fetchRestaurantData = (state, value) => {
  let newState = state;
  return axios
    .post(api.routes.restaurant, { restaurantId: state.restaurantId })
    .then((res) => {
      newState.restaurantTitle = res.data.restaurantTitle;

      res.data.categories.forEach(
        (category) =>
          (newState.categories[category] = {
            loaded: false,
            props: [],
          })
      );
      newState.defaultCategory = res.data.categories[0];
      newState.productsCollection = res.data.productsCollection;
      newState.isLoading = false;

      return axios.post(api.routes.category, {
        productsCollection: res.data.productsCollection,
        categoryId: newState.defaultCategory,
      });
    })
    .then((res) => {
      newState.categories[newState.defaultCategory].props =
        res.data[newState.defaultCategory];
      newState.categories[newState.defaultCategory].loaded = true;
      console.log(newState);
      return newState;
    });
};

我想发生的事情,我认为在reducer中,它不会等待我的响应并使用未定义的值更新上下文状态,然后触发我的错误。

我试图制作一个等待fetchRestaurantData()响应的中间异步函数,但在获得响应之前它仍在更新

1 个答案:

答案 0 :(得分:0)

您应该等待fetchRestaurantData中的响应:

const fetchRestaurantData = async (state, value) => {  // add async keyword to the function 
  let newState = state;
  return await axios  // here add await 
    .post(api.routes.restaurant, { restaurantId: state.restaurantId })
    .then((res) => {
      newState.restaurantTitle = res.data.restaurantTitle;

      res.data.categories.forEach(
        (category) =>
          (newState.categories[category] = {
            loaded: false,
            props: [],
          })
      );
      newState.defaultCategory = res.data.categories[0];
      newState.productsCollection = res.data.productsCollection;
      newState.isLoading = false;

      return axios.post(api.routes.category, {
        productsCollection: res.data.productsCollection,
        categoryId: newState.defaultCategory,
      });
    })
    .then((res) => {
      newState.categories[newState.defaultCategory].props =
        res.data[newState.defaultCategory];
      newState.categories[newState.defaultCategory].loaded = true;
      console.log(newState);
      return newState;
    });
};

有关async functions

的更多信息