我没有使用过 nextjs
,但我想它会发生是因为它在路由器组件的每个渲染上执行。
如果想使用一次,就在组件挂载时的使用效果中调用即可。
useEffect(() => {
checkAuth();
},[]) // This will run once,when the component mounts
,
不需要返回 setState 调用:
const checkAuth = async () => {
const loggedInUsername = await getUsername();
if (router.query.username === loggedInUsername) setAuth(true);
};
还因为您在调用 checkAuth() 函数后立即调用它。在 React 中设置状态会导致重新渲染。所以它被执行 4 到 10 次的原因是因为你的 MyQuestion 组件在你 setState() 时重新渲染,并且当它重新渲染时,再次点击 checkAuth() 函数并且循环重复。
如前所述,将功能放在具有空依赖数组的 useEffect() 中:
useEffect(() => {
const loggedInUsername = await getUsername();
if (router.query.username === loggedInUsername) return setAuth(true);
},[])
,
在什么情况下应该重新运行检查?这就是 useEffect 的用途。 useEffect
接受一个函数来运行所需的效果,以及一个依赖列表来指定何时应该运行效果 -
import { useRouter } from ...
import { useEffect,useState } from "react"
function MyQuestions() {
const router = useRouter()
const [auth,setAuth] = useState(false)
useEffect(async () => {
const loggedInUsername = await getUsername()
if (router.query.username === loggedInUsername)
setAuth(true)
},[getUsername,router.query.username,setAuth])
return <>...</>
}
任何效果内的自由变量必须列为效果的依赖项。不过有一个问题。每次呈现 setAuth
时,MyQuestions
都会是一个新函数。为了确保每次渲染的 setAuth
都相同,我们可以使用 useCallback -
import { useRouter } from ...
import { useEffect,useCallback,setAuth] = useState(false)
const authenticate =
useCallback(_ => setAuth(true),[])
useEffect(async () => {
const loggedInUsername = await getUsername()
if (router.query.username === loggedInUsername)
authenticate()
},authenticate])
return <>...</>
}
现在该效果只会在 getUsername
、router.query.username
或 authenticate
更改时重新运行。考虑到 getUsername
和 authenticate
是函数,不应该改变,我们可以预期效果只会在 router.query.username
改变时重新运行。
本文链接:https://www.f2er.com/5103.html