setState在useEffect中未触发Next.js

pinkon5k  于 2023-03-22  发布在  其他
关注(0)|答案(3)|浏览(164)

我使用的是next.js,在客户端有以下代码。

import { useContext, useEffect, useState } from "react";
import Link from "next/link";
import { UserContext } from "../context";
import { useRouter } from "next/router";

const Nav = () => {
  const [current, setCurrent] = useState("TEST");
  const [state, setState] = useContext(UserContext);
  const router = useRouter();

  // Check first if we are running client side (vs server side)
  // If so, then set state to the pathname. Update on change
  useEffect(() => {
    console.log("router.asPath ", router.asPath);
    console.log("window.location.pathname is ", window.location.pathname);
    console.log(typeof window !== "undefined");
    if (typeof window !== "undefined") {
      console.log("this ran before");
      setCurrent(router.asPath);
      console.log("this ran after");
      console.log("current is ", current);
    }
  }, [typeof window !== "undefined" && window.location.pathname]);
  //...
}

我在控制台得到以下信息...

router.asPath  /register
window.location.pathname is  /register
true
this ran before
this ran after
current is TEST

我可以看到每个console.log()都在useEffect中触发并返回所有正确的值。但是setCurrent()似乎没有触发。为什么?

2wnc66cl

2wnc66cl1#

当代码**完成运行时,**React将检查是否存在状态更新,并且如果存在,useState挂钩的值被更新,并且这导致新的呈现,其中新的值是可用的,因此新的数据被显示在UI中。

const [example,setExemple] = useState("")
//...
const newValue = "new"
setExample(newValue);
console.log(example)// output "" and this is normal

因此,如果你想看到状态的新值,从你正在记录的地方是不可能的,因为组件还没有重新渲染,然而,由于更新状态会导致一个新的渲染console.log,就像JSX中的这样,以便更好地理解发生了什么:

<div className="App">
  {console.log("this is a new render and this is my current : ",current)}
  //...
</div>
weylhg0b

weylhg0b2#

setCurrent将是一个异步操作,因此,原始值将在控制台中输出。
如果您想在状态更新完成后执行操作,可以添加另一个useEffect。
例如,添加this将在每次状态值更新时记录:

useEffect(() => {
    console.log(current);
}, [current]);

这里也有非常明确的解释:https://react.dev/reference/react/useState#ive-updated-the-state-but-logging-gives-me-the-old-value

mcvgt66p

mcvgt66p3#

如果我理解正确的话,您是在问为什么这个“setCurrent(router.asPath);“didn 't fire. it does fire but react does all the set state at the end of the function together.在本例中,在useEffect的末尾。

相关问题