【问题标题】:Items inside archive are not updating on archive url change though archive data is updated reactjs nextjs尽管存档数据已更新,但存档中的项目不会在存档 url 更改时更新 reactjs nextjs
【发布时间】:2022-10-07 01:44:51
【问题描述】:

我现在正在研究一个反应(nextjs)项目。我在后端有产品和多级类别。我从 api 获取数据并将它们显示在 /categories/[slug].jsx 上。已获取并显示了该类别的类别和产品的一些细节。

如果我手动访问类别e.g. http://localhost/categories/category-one,它会正确获取数据并正常工作。在这种情况下,我在此存档页面中有一个侧边栏,用于显示后端的所有可用类别。如果我从/category-one 存档页面的侧边栏中单击每个类别链接e.g. http://localhost/categories/category-two,路径和类别详细信息会更新,但当前类别的新路径中的产品不会更新。仅显示上一个类别的产品。我必须重新加载页面才能看到该类别的正确产品。

我尝试使用 useEffect 进行更新,但没有成功。也许我做的方式是错误的。谁能让我知道如何刷新路径更改类别的产品列表?

这是/categories/[slug].jsx

import { useRouter } from \'next/router\';
import { useEffect, useState } from \'react\';

import ProductArchive from \'/ProductArchive\';

import { getCategory, getCategoryByHierarchy, getCategorySlugs } from \'/libs/categories\';
import { getProductsByCatIds, getProductsCountByCatIds } from \'/libs/products\';

const CategoryScreen = ({ category, productsByCatIds, productsCount, categories }) => {
  const [products, setProducts] = useState(productsByCatIds);
  const [hasMore, setHasMore] = useState(true);

  const router = useRouter();

  const getMoreProducts = async () => {
    const moreProducts = await getProductsByCatIds({
      catId: category.term_id,
      perPage: 16,
      offset: products.length,
    });

    if (moreProducts.code === \'no_product\') return;

    setProducts((products) => [...products, ...moreProducts]);
  };

  useEffect(() => {
    console.log(\'path got changed\');
  }, [router.asPath]);

  useEffect(() => {
    setHasMore(productsCount > products.length ? true : false);
  }, [productsCount, products]);

  return (
    <>
      <ProductArchive
        products={products}
        getMoreProducts={getMoreProducts}
        hasMore={hasMore}
        productsCount={productsCount}
        banner={{ heading: category.name, i2Text: category.name }}
        data={categories}
      />
    </>
  );
};

export const getStaticPaths = async () => {
  const paths = await getCategorySlugs();

  return {
    paths,
    fallback: \'blocking\',
  };
};

export const getStaticProps = async ({ params }) => {
  const category = await getCategory(params.slug);

  if (!category) {
    return {
      notFound: true,
    };
  }

  const productsByCatIds = await getProductsByCatIds({
    catId: category.id,
    perPage: 16,
  });

  const productsCount = await getProductsCountByCatIds({
    catId: category.id,
  });

  const categories = await getCategoryByHierarchy();

  const data = { category, productsByCatIds, productsCount, categories };

  return {
    props: data || {},
    revalidate: 1,
  };
};

export default CategoryScreen;

这是/ProductArchive.jsx

import Link from \'next/link\';
import DefaultBanner from \'./DefaultBanner\';
import ProductCard from \'./ProductCard\';
import Sidebar from \'./Sidebar\';

import InfiniteScroll from \'react-infinite-scroll-component\';
import DefaultLoader from \'./DefaultLoader\';
import { thousandSeparator } from \'../../libs/functions/thousandSeparator\';

const ProductArchive = ({ banner, products, getMoreProducts, hasMore, productsCount, data }) => {
  return (
    <section>
      <DefaultBanner heading={banner.heading} i2Text={banner.i2Text} />

      <div className=\"container\">
        <div className=\"grid-view\">
          <div className=\"col-1\">
            <Sidebar data={data} />
          </div>

          <div className=\"col-2\">
            <div className=\"relative\">
              {productsCount > 0 && (
                <small className=\"total\">
                  Total: {thousandSeparator(productsCount)}
                </small>
              )}
            </div>
            {productsCount > 0 ? (
              <InfiniteScroll
                dataLength={products.length}
                next={getMoreProducts}
                hasMore={hasMore}
                loader={<DefaultLoader />}
                endMessage={<p></p>}
                scrollThreshold=\"0.5\"
              >
                <div className=\"another-grid\">
                  {products.length > 0 ? (
                    products.map((product, index) => {
                      return (
                        <ProductCard
                          key={product.id}
                          index={index}
                          product={product}
                        />
                      );
                    })
                  ) : (
                    <div>
                      <h4 className=\"text-xl\">Oops... No products found.</h4>
                      <p className=\"mt-2 font-thin\">
                        <Link href=\"/\">
                          <a>Go back to homepage</a>
                        </Link>
                      </p>
                    </div>
                  )}
                </div>
              </InfiniteScroll>
            ) : (
              <div>No products found.</div>
            )}
          </div>
        </div>
      </div>
    </section>
  );
};

export default ProductArchive;

    标签: reactjs next.js


    【解决方案1】:

    我能够通过使用 Vercel 的 swr 包来解决这个问题。

    在解决方案中,我只使用 getStaticProps 获取前 16 个产品,其余的使用 useSWRInfinite 获取。如果您不需要分页或无限加载更多,您也可以使用 useSWR 。希望这对其他人有帮助。

    【讨论】:

      猜你喜欢
      • 2015-02-09
      • 2021-09-12
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 2014-03-06
      • 2015-07-29
      • 1970-01-01
      相关资源
      最近更新 更多