I'm working on a component for a chrome extension that needs to listen for messages passed from other parts of the extension and update the display based on those messages.

A simplified version of what I thought should work is below but it does not do what I would expect.

This snippet successfully receives the message and calls the increment function, but never increments passed 1, with the log just repeating `Incrementing 0 -> 1`

```
// app.jsx
import React from 'react'
import { createRoot } from "react-dom/client";

function App() {
    const [ counter, setCounter ] = React.useState(0)

    function increment() {
        console.log("Incrementing ", counter, " -> ", (counter + 1));
        setCounter(counter + 1)
    }

    React.useEffect(() => {
        chrome.runtime.onMessage.addListener(message => increment())
    }, [ ])

    return <h1>Counter: {counter}</h1>
}

createRoot(document.getElementById('root')).render(<App />)

```

After some experimentation I discovered that if I set an intermediary value, and then update the counter via a seperate effect, as in the snippet below, it works exactly as I would expect.

```
// app.jsx
import React from 'react'
import { createRoot } from "react-dom/client";

function App() {
    const [ counter, setCounter ] = React.useState(0)
    const [ message, setMessage ] = React.useState()

    function increment() {
        console.log("Incrementing ", counter, " -> ", (counter + 1));
        setCounter(counter + 1)
    }

    React.useEffect(() => {
        chrome.runtime.onMessage.addListener(message => setMessage(message))
    }, [ ])

    React.useEffect(() => increment(), [ message ])

    return <h1>Counter: {counter}</h1>
}

createRoot(document.getElementById('root')).render(<App />)

```

The message sending is identical in both versions and working as expected in both cases. It is just a sendMessage call from a content script.

```
// contentScript.js
chrome.runtime.sendMessage({action: 'INCREMENT' })

```

This solution is acceptable, but I'm having trouble understanding why the second works as expected when the first does not.

Is anyone able to explain this behaviour?