Home > Enterprise >  Component is rendering one step behind
Component is rendering one step behind

Time:01-10

I have to press sort twice for the items to be rendered, and they are rendered with what should've been rendered on the first press. So it's one step behind. Any idea why it is not being rendered on the first press and why it's one step behind?

I tried making it asynchronous, I tried making a loading state and then render, but everything to no effect.

Here is my code:

import "./productlist.scss";
import ProductCard from "../../../../Main Page Components/Trending Now/Product/ProductCard";
import { Link } from "react-router-dom";
import { useSelector } from "react-redux";
import { useEffect } from "react";
import { useState } from "react";

const ProductList = (props) => {
  const sortType = useSelector((state) => state.sort).sortType;
  const [sortedProducts, setSortedProducts] = useState(props.products);
  // const [isSorted, setIsSorted] = useState(false);
  useEffect(() => {
    setSortedProducts(sortProducts(sortedProducts, sortType));
  }, [sortType, sortedProducts]);

  const sortProducts = (products, sortMode) => {
    console.log("sortMode", sortMode);
    switch (sortMode) {
      case "A-Z":
        return products.sort((a, b) => a.name.localeCompare(b.name));

      case "Z-A":
        return products.sort((a, b) => a.name.localeCompare(b.name)).reverse();

      case "default":
        return products;
    }
  };

  return (
    <div className="product-list padding">
      <div className="product-list-contents">
        {sortedProducts.map((singleProduct) => {
          console.log("singleProduct", singleProduct.name);
          // if(product.categories[0].name.slice(0,1).toLowerCase() === props.category){
          return (
            <Link
              to={`/product/${singleProduct.sku}`}
              className="product-list-link"
              key={singleProduct.sku}
            >
              <ProductCard product={singleProduct} />
            </Link>
          );
          // )}
          // }
        })}
      </div>
    </div>
  );
};

export default ProductList;

CodePudding user response:

It seems that the useEffect is both setting and listening to sortedProducts which might be causing error.

Assuming that sortedProducts is based on products from props, and sortType is updated by useSelector, perhaps this component can sort props.products without keeping a state and useEffect. For a rough example:

const ProductList = (props) => {
  const { sortType } = useSelector((state) => state.sort);
  const sortProducts = (products, sortMode) => {
    console.log("sortMode", sortMode);
    switch (sortMode) {
      case "A-Z":
        return products.sort((a, b) => a.name.localeCompare(b.name));
      case "Z-A":
        return products.sort((a, b) => a.name.localeCompare(b.name)).reverse();
      case "default":
        return products;
    }
  };
  const sortedProducts = sortProducts(props.products, sortType);

  return (
    <div className="product-list padding">
      <div className="product-list-contents">
        {sortedProducts.map((singleProduct) => {
          console.log("singleProduct", singleProduct.name);
          // if(product.categories[0].name.slice(0,1).toLowerCase() === props.category){
          return (
            <Link
              to={`/product/${singleProduct.sku}`}
              className="product-list-link"
              key={singleProduct.sku}
            >
              <ProductCard product={singleProduct} />
            </Link>
          );
          // )}
          // }
        })}
      </div>
    </div>
  );
};

export default ProductList;
  • Related