【问题标题】:React useContext() returns undefined反应 useContext() 返回未定义
【发布时间】:2020-07-11 19:07:37
【问题描述】:

我的上下文提供程序有这段代码,我已经包装了组件,但是当我尝试使用 useProductState 或 useProductDispatch 在孩子中使用它时,它返回未定义(抛出错误);

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 };

有人可以解释这是如何工作的吗,我正在尝试访问状态并分派到一个功能组件中,该组件是 .

更新:

我已经把它作为我的减速器的一个动作

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() 响应,但它在得到响应之前仍在更新

【问题讨论】:

  • 我看到你正在导出你的自定义钩子而不是上下文,我会将它们添加到底部的导出中。也许这是导致问题的原因
  • 好吧,我在 reducer 操作中使用 api 调用,我认为我的消费者在响应更改我的状态之前触发了重新渲染,这就是为什么我的上下文返回为未定义的原因,但我不知道该怎么做做

标签: javascript reactjs


【解决方案1】:

你应该等待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的信息

【讨论】:

    猜你喜欢
    • 2021-07-19
    • 2019-12-13
    • 2019-12-24
    • 2023-04-06
    • 1970-01-01
    • 2020-12-08
    • 2021-07-02
    相关资源
    最近更新 更多