组件卸载时停止执行我的 React for 循环

Posted

技术标签:

【中文标题】组件卸载时停止执行我的 React for 循环【英文标题】:Stop my React for loop from executing when component umounts 【发布时间】:2022-01-13 22:15:19 【问题描述】:

当我的组件卸载时,我正试图阻止 for 循环运行。

孤立的例子如下:

我的小部件是一台打印机。当打印机打开时,它会打印“hello world”1M 次。当打印机关闭时,它会停止。

我的问题是打印机在关闭时无法停止打印。当我关闭打印机时,for 循环继续运行。我认为我可以通过更新isOpen 来阻止打印机打印。但是当我关闭打印机时,for 循环范围内的 isOpen 变量似乎卡在了true 上。卸载此组件时如何中断 for 循环的运行?

我似乎对反应状态和函数如何协同工作有一些基本的误解。

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

【问题讨论】:

【参考方案1】:

React 组件函数只是常规的旧函数。您的 runThePrinter 函数也只是一个常规的旧同步函数,因此您的组件的渲染周期将如下所示(显然这已被简化):

    React 在某处(可能是您的 App 组件)看到一个 &lt;SelectionPrinter isOpen=true /&gt; 组件并调用 SelectionPrinter 函数。

    SelectionPrinter 函数运行:它实例化了两个函数,runThePrinterprint

    React 调用你的效果函数,而后者又调用你的runThePrinter 函数。此函数循环一百万次迭代并打印isOpen 状态或true 一百万次。

如果您在步骤 1-3 中的任何一个步骤中更改了 prop isOpen,这无关紧要 - React 将使用新的 props 和 state 排队一个新的渲染,但它不会神奇地中断已经被调用。就像函数通常没有任何特殊的“观察者”或除了调用它们的变量之外的任何知识一样,React 组件函数只是使用 props 和 state 调用的函数。当这些组件中的 props 或 state 发生变化时,React 会使用新的现实调用它们的函数,但它不会中断函数以“注入”新的 props 或 state - 它只是调用函数。

我强烈推荐 Dan Abramov 的 this article,它名义上是关于 useEffect 的,但它揭示了一些常见的 React 误解。

【讨论】:

我的解释有点忘乎所以,并没有真正完全回答您的问题 - 如果您想查看“最新”的内容,即存储一个始终是最新的可变值,请查看useRef。这几乎就像选择退出我上面描述的行为 - React 会在每次渲染时为您提供相同的 ref 对象,您可以随意更改它。但它不会触发重新渲染。 感谢您的得意忘形!您的解释真的很有帮助 + 我将这篇文章添加到我的 TODO 中。你摇滚。

以上是关于组件卸载时停止执行我的 React for 循环的主要内容,如果未能解决你的问题,请参考以下文章

React-Router 组件在转换时卸载

React - 循环的每个元素的随机背景颜色

React 功能组件在重新挂载后停止渲染状态更改

如何在for循环中设置react ref

React Native:当您离开一个组件时,该组件是不是会被卸载?

react父子组件生命周期执行顺序