javascript 在contex提供程序中从API获取数据时如何在useEffect中实现cleanup函数

wz3gfoph  于 2023-01-01  发布在  Java
关注(0)|答案(1)|浏览(117)

我想根据从API中获取的特定类别显示产品列表,如下所示:

const API = "https://dummyjson.com/products";

const ProductsList = () => {
  const { cate } = useParams(); //here I am getting category from Viewall component
  const { getFilterProducts, filter_products } = useFilterContext();
  useEffect(() => {
    getFilterProducts(`${API}/category/${cate}`);
  }, [cate]);
  return (
    <div className="mx-2 mt-2 mb-16 md:mb-0 grid grid-cols-1 md:grid-cols-12">
      <div className="h-9 w-full md:col-span-2">
        <FilterSection />
      </div>
      <div className="md:col-span-10">
        <ProductListDetails products={filter_products} />
      </div>
    </div>
  );
};

我的过滤上下文提供程序如下所示

const initialState = {
  filter_products: [],
};

const FilterProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState);
  const { products } = useAppContext();
  const getFilterProducts = async (url) => {
    dispatch({ type: "FILTERS_LOADING" });
    try {
      const res = await fetch(url);
      const data = await res.json();
      if (!res.ok) {
        var error = new Error("Error" + res.status + res.statusText);
        throw error;
      }
      dispatch({ type: "LOAD_FILTER_PRODUCTS", payload: data.products });
    } catch (err) {
      dispatch({ type: "FILTERS_ERROR", payload: err.message });
    }
  };
  return (
    <FilterContext.Provider value={{ ...state, getFilterProducts }}>
      {children}
    </FilterContext.Provider>
  );
};

我尝试在ProductList组件中使用这个简单的方法来清理:

useEffect(() => {
  let inView = true;
  getFilterProducts(`${API}/category/${cate}`);

  return () => {
    inView = false;
  };
}, [cate]);

但是它似乎不起作用。当我移动到ProductList组件时,它首先显示我以前的filer_products值的数据,然后在几分之一秒后,更新数据并显示当前数据。我期望当ProductList组件卸载时,它的渲染数据应该消失,当我再次导航它时,它应该直接渲染当前数据。而不是在几秒钟之后。

n8ghc7c1

n8ghc7c11#

正如您所解释的,我假设您的上下文正在 Package 您的路由,并且在页面之间切换时不会重新呈现。一个简单的解决方案是在ProductsList中有一个加载器,等待新数据替换旧数据,并让用户注意加载器发生的事情:

const ProductsList = () => {
  const { cate } = useParams(); //here I am getting category from Viewall component
  const { getFilterProducts, filter_products } = useFilterContext();
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    getFilterProducts(`${API}/category/${cate}`).then(() => {
      setLoading(false);
    });
  }, [cate]);

  if (loading) {
    return <p>Hang tight, the data is being fetched...</p>;
  }
  return (
    <div className="mx-2 mt-2 mb-16 md:mb-0 grid grid-cols-1 md:grid-cols-12">
      <div className="h-9 w-full md:col-span-2">
        <FilterSection />
      </div>
      <div className="md:col-span-10">
        <ProductListDetails products={filter_products} />
      </div>
    </div>
  );
};

如果需要在clean-up函数中清除存储,可以将dispatch添加为上下文值的一部分,在ProductsList中获取它,并如下调用:
x一个一个一个一个x一个一个二个x

相关问题