barciewicz
barciewicz

Reputation: 3783

Make React hook step into loop

How can I adjust the below code so that after "loop" button is pressed, and then "change data" button is pressed, I can see the loop print changed data - that is, "bar" not "foo"?

https://codesandbox.io/s/react-hooks-playground-forked-gn5yw

const sleep = async(ms: number) => new Promise(r => setTimeout(r, ms))

const Looper = () => {

    const [data, setData] = React.useState<string>('foo')

    const runOnce = () => {
        console.log(data)
    }

    const loop = async() => {
        while (true) {
            runOnce()
            await sleep(1000)
        }
    }

    return (
        <div>
            <button onClick={loop}>Loop</button>
            <button onClick={runOnce}>Run once</button>
            <button onClick={() => setData('bar')}>Change data in state</button>
        </div>
    )
}

Upvotes: 0

Views: 34

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370759

Since the data change doesn't result in any visual changes in the component, it doesn't need to be state. The runOnce function containing the data from the old closure is the problem (data is declared with const, after all - it can't change for a given invocation of loop)

Use a ref instead:

const dataRef = useRef('foo');
const runOnce = () => {
    console.log(dataRef.current)
}
<button onClick={() => { dataRef.current = 'bar'; }}>Change data in state</button>

Upvotes: 1

Related Questions