我想有条件地在 Next.js 上呈现页面
Posted
技术标签:
【中文标题】我想有条件地在 Next.js 上呈现页面【英文标题】:I want to render the page on Next.js conditionally 【发布时间】:2021-06-04 16:48:37 【问题描述】:我的 -app.js 上有以下代码:
import useState, useEffect from "react";
import PropTypes from "prop-types";
...
export default function MyApp(props)
const Component, pageProps = props;
const [cartItems, setCartItems] = useState([]);
//this prop will be passed to all the pages
const passedProps =
...pageProps,
cartItems: cartItems,
setCartItems: setCartItems,
;
...
//on App load do the following:
useEffect(() =>
...
//get cart items from localstorage if exist,else set to empty array;
const savedCartItems = localStorage.getItem("cartItems"),
cartItems = JSON.parse(savedCartItems) || [];
setCartItems(cartItems);
, []);
return (
...
<Component ...passedProps />
...
</>
);
MyApp.propTypes =
Component: PropTypes.elementType.isRequired,
pageProps: PropTypes.object.isRequired,
;
以下是 checkout.js 上的代码
import useEffect, useState from "react";
import PropTypes from "prop-types";
import useRouter from "next/router";
...
export default function Checkout(props)
router = useRouter(),
cartItems = props;
...
// on checkout page load if cart is empty redirect to carts page
useEffect(() =>
!cartItems.length && router.push("/cart");
, [cartItems, router]);
...
return (
...
Checkout.propTypes =
cartItems: PropTypes.arrayOf(
PropTypes.shape(
title: PropTypes.string,
variations: PropTypes.objectOf(PropTypes.object),
qty: PropTypes.number,
price: PropTypes.number,
)
),
;
仅当购物车为空时,我才需要从结帐页面重定向到购物车页面,但即使购物车中有商品,我每次都会被重定向。我认为这是因为在初始页面加载时,项目仍未从本地存储加载到父应用程序组件并且仍未定义。有什么解决办法吗??
【问题讨论】:
那么您是否希望重定向仅在页面加载时发生?如果有人稍后在页面上向卡片添加项目,它不应该重定向吗? 结帐是一个单独的页面。如果购物车中没有商品,结帐应立即重定向。假设有人在 url 中键入以下地址:localhost/checkout。现在如果购物车是空的,他应该被重定向到购物车页面。你明白我的意思了吗?? 你的路由器是否响应路由器 dom? 没有它的“下一个/路由器”。 它不是路由器问题,它的发生是因为使用效果,由于 next.js 中的 s-s-r,我必须在 useEffect 中重定向。问题是一开始没有从本地存储中加载项目并且购物车是空的。 【参考方案1】:您的问题是因为您使用长度为 0 的空数组初始化 cartItems
,因此始终执行:
!cartItems.length && router.push("/cart");
相反,将其初始化为不带值:
const [cartItems, setCartItems] = useState();
并将 useEffect 更改为:
// on page Load,if cart is empty redirect to carts page
useEffect(() =>
if (Array.isArray(cartItems) && cartItems.length === 0)
router.push("/cart");
, [cartItems, router]);
这样,重定向只会在以下情况下执行:
-
cartItems 已在父项中设置
不为空。
【讨论】:
!cartItems.length 将在非空数组上返回 false 并且不应执行。仅当长度值为 0 时才会执行。因为零是虚假的,大于零是真实的。我之前尝试过。问题不在于初始化,而在于将项目从本地存储加载到父级。我已经试过你的答案了。 developer.mozilla.org/en-US/docs/Glossary/Falsy null 和 undefined 也是虚假的。所以当用于条件语句时,零等于 null 或 undefined 我明白什么是虚假值。总是执行,我的意思是在初始反应渲染时,状态用一个空数组初始化,所以检查返回 true。然后从本地存储中获取项目的父级中的 useEffect 发生,它更新状态,但此时重定向已经发生。如果你说你已经尝试过了,但它不起作用,那么你能发一个minimal, reproducible example吗? 没问题,falsy 正是我使用Array.isArray
来明确检查localStorage 操作是否已经发生而不是!carsItems.length
的原因,因为即使您初始化为空。
抱歉,这是我的错误,已编辑修复!以上是关于我想有条件地在 Next.js 上呈现页面的主要内容,如果未能解决你的问题,请参考以下文章
Next.js 中奇怪的命令式 onScroll 路由行为(仅在服务器上呈现)
在 Next.js 中为 styled-jsx 动态添加样式