Next.js 即使在页面刷新时满足条件,useEffect 的 useRouter 也会推送
Next.js useRouter with useEffect pushes even if condition is met on page refresh
我 运行 遇到 useRouter
和 useEffect
的问题,如果不满足特定条件,我想重定向用户。
在第 1 页上,您 select 一个 amount
被传递到上下文并在第 2 页上检索。
在第 2 页我有这个情况:
import { useEffect, useContext } from "react";
import { useRouter } from "next/router";
import AppContext from "../context/AppContext";
const PageTwo = () => {
const { amount } = useContext(AppContext);
const router = useRouter();
useEffect(() => {
if (!amount || amount == null) {
router.push("/page-1"); // redirect if no amount is selected
}
});
return (
...
);
};
当我们到达第 2 页时,我看到了 amount
,但是当您刷新页面时,即使设置了 amount
,它也会将您引导回 page-1
。当您直接转到 page-2
时效果很好,没有 select 在 page-1
上输入金额,它会将您重定向回 page-2
。
在这种情况下,上下文 API 和/或 useRouter 和 useEffect 的工作方式可能有问题。
这是一个有问题的 CodeSanBox 示例:
https://codesandbox.io/s/next-js-userouter-with-useeffect-6645u?file=/pages/page-2.js
在 clearAmount
函数和 _app 文件的 useState("")
中将 null 更改为空字符串 ("")
而不是 (null)
。另外,将您的 if 语句更改为 if (amount === "")
。这修复了它,这是我从你的沙箱中分叉出来的沙箱。 https://codesandbox.io/s/next-js-userouter-with-useeffect-forked-t2enf?file=/pages/page-2.js
出现这种行为是因为即使在上下文中设置了新的 amount
值后,重新加载页面时其初始值在第一次呈现时仍将是 null
,这发生在应用程序检查并设置 localStorage
值。这触发重定向 before setAmount(amount)
被调用 localStorage
.
要通过最小的更改来防止这种情况,您可以将触发重定向的检查修改为以下内容。确保还将 amount
添加到 useEffect
的依赖项数组。
useEffect(() => {
if (amount === "") {
router.push("/page-1");
}
}, [amount]);
如果没有存储任何值,您还必须将 _app
中传递给 setAmount
的值更改为默认为空字符串。
useEffect(() => {
const amount = localStorage.getItem("amount") ?? "";
setAmount(amount);
}, []);
这允许我们为初始状态值 (null
) 和空值 (""
) 设置不同的值。这意味着在 amount
被存储在 localStorage
.
中的值更新之前不会发生重定向
最后,为了保持逻辑一致,您必须更新 clearAmount
函数以将 amount
设置为空值。
const clearAmount = () => {
setAmount("");
};
我 运行 遇到 useRouter
和 useEffect
的问题,如果不满足特定条件,我想重定向用户。
在第 1 页上,您 select 一个 amount
被传递到上下文并在第 2 页上检索。
在第 2 页我有这个情况:
import { useEffect, useContext } from "react";
import { useRouter } from "next/router";
import AppContext from "../context/AppContext";
const PageTwo = () => {
const { amount } = useContext(AppContext);
const router = useRouter();
useEffect(() => {
if (!amount || amount == null) {
router.push("/page-1"); // redirect if no amount is selected
}
});
return (
...
);
};
当我们到达第 2 页时,我看到了 amount
,但是当您刷新页面时,即使设置了 amount
,它也会将您引导回 page-1
。当您直接转到 page-2
时效果很好,没有 select 在 page-1
上输入金额,它会将您重定向回 page-2
。
在这种情况下,上下文 API 和/或 useRouter 和 useEffect 的工作方式可能有问题。
这是一个有问题的 CodeSanBox 示例:
https://codesandbox.io/s/next-js-userouter-with-useeffect-6645u?file=/pages/page-2.js
在 clearAmount
函数和 _app 文件的 useState("")
中将 null 更改为空字符串 ("")
而不是 (null)
。另外,将您的 if 语句更改为 if (amount === "")
。这修复了它,这是我从你的沙箱中分叉出来的沙箱。 https://codesandbox.io/s/next-js-userouter-with-useeffect-forked-t2enf?file=/pages/page-2.js
出现这种行为是因为即使在上下文中设置了新的 amount
值后,重新加载页面时其初始值在第一次呈现时仍将是 null
,这发生在应用程序检查并设置 localStorage
值。这触发重定向 before setAmount(amount)
被调用 localStorage
.
要通过最小的更改来防止这种情况,您可以将触发重定向的检查修改为以下内容。确保还将 amount
添加到 useEffect
的依赖项数组。
useEffect(() => {
if (amount === "") {
router.push("/page-1");
}
}, [amount]);
如果没有存储任何值,您还必须将 _app
中传递给 setAmount
的值更改为默认为空字符串。
useEffect(() => {
const amount = localStorage.getItem("amount") ?? "";
setAmount(amount);
}, []);
这允许我们为初始状态值 (null
) 和空值 (""
) 设置不同的值。这意味着在 amount
被存储在 localStorage
.
最后,为了保持逻辑一致,您必须更新 clearAmount
函数以将 amount
设置为空值。
const clearAmount = () => {
setAmount("");
};