无法按 createdAt 对项目进行排序

Can't sort items by createdAt

我正在关注 this tutorial 一个电子商务网站并应用排序功能。

我已经将我的代码与源代码进行了比较,我认为教程使用的方法没有区别,所以我现在有点困惑。

这里是导师的source code

问题描述:

-> 问题:在这种情况下,我们将如何解决这个问题,或者是否有更好的方法根据创建日期对项目进行排序?




下面是我的代码:

产品架构

const mongoose = require('mongoose')

const ProductSchema = new mongoose.Schema(
  {
    title: {
      type: String, 
      required: true, 
    },
    desc: {
      type: String,
      required: true,
    },
    img: {
      type: String,
      required: true,
    },
    categories: {
      type: Array,
      required: true,
    },
    size: {
      type: Array,
    },
    color: {
      type: Array,
    },
    price: {
      type: Number,
      required: true,
    },
    inStock: {
      type: Boolean,
      default: true
    }
  }, 
  { timestamps: true }
)

module.exports = mongoose.model("Product", ProductSchema)

Products.js

const Products = ({ category, filters, sort }) => {

  const [products, setProducts] = useState([])
  const [filteredProducts, setFilteredProducts] = useState([])

  useEffect(() => {
    category && setFilteredProducts(
      products.filter(item => 
        Object.entries(filters).every(([key, value]) => 
          item[key].includes(value)
        )
      )
    )
  }, [category, filters, products])

  // Sorting:
  useEffect(() => {
    // Sort by latest date:
    if (sort === "latest") {
      setFilteredProducts(prev =>
        [...prev].sort((a, b) => 
          a.createdAt - b.createdAt
          // console.log(a.createdAt - b.createdAt) -> This returns "NaN"
        )
      )
    } else if (sort === "asc") {
      setFilteredProducts(prev =>
        [...prev].sort((a, b) => a.price - b.price)
      )
    } else if (sort === "desc") {
      setFilteredProducts(prev =>
        [...prev].sort((a, b) => b.price - a.price)
      )
    } else {
      // Sort by oldest date:
      setFilteredProducts(prev =>
        [...prev].sort((a, b) => b.createdAt - a.createdAt)
      )
    }
  }, [sort])

  return (
    <Container>
      <Title>Popular In Store</Title>
      <ProductsWrapper>
        {filteredProducts.map(item => (
        <Product key={item.id} item={item} />
      ))}
      </ProductsWrapper>
    </Container>
  );
}

createdAt 属性 是一个 non-number-like 字符串,因此尝试对它们进行算术运算将导致 NaN.

console.log("2022-04-03T07:55:18.556Z" - "2022-04-12T07:55:18.556Z"); // NaN

使用 String.prototype.localeCompare() 在排序比较器中比较字符串值。

console.log("2022-04-03T07:55:18.556Z".localeCompare("2022-04-12T07:55:18.556Z")); // -1

示例:

// Sorting:
useEffect(() => {
  // Sort by latest date:
  if (sort === "latest") {
    setFilteredProducts(prev =>
      [...prev].sort((a, b) => a.createdAt.localeCompare(b.createdAt)
    ))
  } else if (sort === "asc") {
    setFilteredProducts(prev =>
      [...prev].sort((a, b) => a.price - b.price)
    )
  } else if (sort === "desc") {
    setFilteredProducts(prev =>
      [...prev].sort((a, b) => b.price - a.price)
    )
  } else {
    // Sort by oldest date:
    setFilteredProducts(prev =>
      [...prev].sort((a, b) => b.createdAt.localeCompare(a.createdAt))
    )
  }
}, [sort]);

请注意,这仅在日期字符串按单位大小的降序使用单位时有效,即年、月、日等...因此请确保您的日期符合此要求。如果这不切实际,那么您将需要求助于将日期字符串处理为 DateTime 对象并使用其他比较方法。

console.log(new Date("2022-04-03T07:55:18.556Z") - new Date("2022-04-12T07:55:18.556Z")); // -777600000