I'm trying to stop a for loop from running when my component unmounts.
The isolated example is as follows:
My widget is a printer. When the printer is open, it prints "hello world" 1M times. And when the printer is closed it stops.
My problem is that I can't get the printer to stop printing when its closed. When I close the printer, the for loop continues to run. I thought that I would be able to stop the printer from printing by updating isOpen
. But when I close the printer, the isOpen variable, in the scope of the for loop seems to be stuck on true
. How can I interrupt the for loop from running when this component dismounts?
I seem to have some fundamental misunderstanding about how react state and functions work together.
const SelectionPrinter = (props: {isOpen: boolean}): JSX.Element => {
useEffect(() => {
runThePrinter()
}, [props.isOpen])
const runThePrinter = (isOpen: boolean) => {
for (let x = 0; x < 1000000; x ) {
if (isOpen) {
print(isOpen)
}
}
}
const print = (isOpen: boolean) => {
setTimeout(() => {
if (isOpen) {
console.log("hello world")
} else {
console.log("goodbye")
}
})
}
return (<div> Printer </div>)
export default SelectionPrinter
CodePudding user response:
React component functions are just regular old functions. Your runThePrinter
function is also just a regular old synchronous function, so a render cycle for your component will go something like this (obviously this has been simplified):
React sees a
<SelectionPrinter isOpen={true} />
component somewhere (maybe your App component) and calls theSelectionPrinter
function.The
SelectionPrinter
function runs: it instantiates two functions,runThePrinter
andprint
.React calls your effect function, which in turn calls your
runThePrinter
function. This function loops for a million iterations and prints theisOpen
state, ortrue
a million times.
If you changed the prop isOpen
during any of steps 1-3, it wouldn't matter - React will queue up a new render with the new props and state but it won't magically interupt a function that has already been called. Just like functions normally wouldn't have any special "watchers" or knowledge of anything beyond the variables they were called with, React component functions are just functions that are called with props and state. When props or state changes in these components, React calls their functions with the new reality, but it's not like it will interrupt a function to "inject" new props or state - it just calls the function.
I highly recommend this article by Dan Abramov, which is nominally about useEffect but sheds a lot of light on some common React misconceptions.