React useState with addEventListener

Paweł Baca :

Can someone explain to me exactly why the callback from addEventListener after changing value (by click button) in useState from "init" to "new state" shows the value "init" while text in button is "new state"

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>
    )
}
kooskoos :

Empty dependency array acts as componentDidMount. You should add test as one of the dependencies so it fires again

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>
    )
}

Another reason this is happening is the functional component is using stale state value.

Event is registered once on component mount with useEffect. It's the same function during entire component lifespan and refers to stale state that was fresh at the time when this eventListener was defined the first time.

The solution for that is using refs

Check out https://codesandbox.io/s/serverless-thunder-5vqh9 to understand the solution better

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=220743&siteId=1