用addEventListener反应useState

时间:2020-03-10 14:42:57

标签: javascript reactjs react-hooks addeventlistener

有人可以向我确切解释为什么useState中的值(通过单击按钮)从“ init”更改为“ new state”时,通过addEventListener进行回调的原因,而按钮中的文本为“ new state”时却显示值“ init”

function Test() {
    const [test, setTest] = useState("init")
    useEffect(() => {
        window.addEventListener("resize", () => console.log(test))
    }, [])

    return (
        <button style={{ marginTop: "100px" }} onClick={() => setTest("new state")}>
            {test}
        </button>
    )
}

3 个答案:

答案 0 :(得分:5)

test添加到useEffect中的依赖项数组中:

useEffect(() => {
  const func = () => console.log(test);
  window.addEventListener("resize", func)
  return () => {
    window.removeEventListener("resize", func)
  }
}, [test])

Hooks常见问题解答:Why am I seeing stale props or state inside my function?

中解释了为什么需要这样做

您看到过时的道具或状态的另一个可能原因是,如果您 使用“依赖项数组”优化,但未正确指定 所有的依赖。例如,如果效果将[]指定为 第二个参数,但在内部读取someProp,它将继续“看到” someProp的初始值。解决方案是删除 依赖项数组,或对其进行修复。

答案 1 :(得分:2)

空依赖性数组充当componentDidMount。您应该将测试添加为依赖项之一,以便再次触发

function Test() {
    const [test, setTest] = useState("init")
    useEffect(() => {
        window.addEventListener("resize", fun)
        return () => {
        window.removeEventListener("resize", fun)
    }
    }, [test])

    return (
        <button style={{ marginTop: "100px" }} onClick={() => setTest("new state")}>
            {test}
        </button>
    )
}

发生这种情况的另一个原因是功能组件正在使用过时的状态值。

使用useEffect在组件安装中注册一次事件。在整个组件生命周期中,它具有相同的功能,并且是指在首次定义此eventListener时新鲜的过时状态。

解决方案是使用引用

查看https://codesandbox.io/s/serverless-thunder-5vqh9可以更好地了解解决方案

答案 2 :(得分:1)

一次触发的效果内的状态永远不会更新(如果使用[])

useEffect范围内的“ test”值永远不会更新,因为该效果在安装时仅触发了一次。 除非再次触发“效果”,而是将一个参数传递到方括号中,否则您随后进行的“状态更改”将永远不会更改此值。