我的方法可能是反对 SSR 的,但我想实现的是,在用户访问 /products
时呈现所有产品,并通过简单的 products.map(...)
呈现完美。我还有一个类别过滤器,我确实为该复选框设置了一个 onClick,它基本上路由到 /products?category=${categoryName}
它设置了 url,控制台记录的过滤产品是正确的,但不会更新第一个呈现的产品。
这是我的 getServerSideProps
;
export const getServerSideProps = async (context) => {
const { db } = await connectToDatabase();
const getcategoriesFromDB = await db
.collection('categories')
.find({})
.toArray();
const getcategories = await JSON.parse(JSON.stringify(getcategoriesFromDB));
if (
!(
Object.keys(context.query).length === 0 &&
context.query.constructor === Object
)
) {
console.log('if fired!');
console.log(context.query);
const category = context.query.category;
const getFilteredProducts = await db
.collection('products')
.find({
category: category,})
.toArray();
const getProducts = await JSON.parse(JSON.stringify(getFilteredProducts));
console.log(getProducts);
return {
props: {
getcategories,getProducts,},};
} else {
console.log('else fired!');
const getProductsFromDB = await db
.collection('products')
.find({})
.toArray();
const getProducts = await JSON.parse(JSON.stringify(getProductsFromDB));
return {
props: {
getcategories,};
}
};
这里是一些状态和useEffect;
const Products = ({ getcategories,getProducts }) => {
const classes = useStyles();
const [products,setProducts] = useState(getProducts);
const [categories,setCategories] = useState([]);
const router = useRouter();
console.log(products);
console.log(categories);
useEffect(() => {
if (categories.length === 0) {
setProducts(getProducts);
}
},[categories,products]);
const addToFilter = async (e) => {
const categoryName = e.currentTarget.dataset.category;
if (categories.length === 0) {
setCategories([...categories,categoryName]);
}
router.push(
`${process.env.NEXT_PUBLIC_URL}/products?category=${categoryName}`
);
};
这是我渲染产品的div;
{products.map((product) => (
<Grid
item
md={3}
xs={6}
classname={classes.productCardWrapper}
key={product._id}
>
<div classname={classes.productCard}>
<div classname={classes.productImageWrapper}>
<Image
src={product.image[0].secure_url}
alt={`${process.env.NEXT_PUBLIC_URL} ${product.name}`}
height={300}
width={450}
/>
</div>
<Typography classname={classes.productCardTypo}>
{product.name}
</Typography>
<Typography variant='h6' classname={classes.productCardTypo}>
€{product.price}
</Typography>{' '}
我已经习惯了 NextJS,所以我不确定我的方法是否正确。
正如我所说,我在 vscode 终端上获取了过滤后的产品,但浏览器仍然记录了旧产品控制台。