简体   繁体   English

在新的 state 上反应原生中断循环或卸载

[英]React native break loop on new state or unmount

I have a React component where I want to create a loop when it's mounted and stop the loop when it's unmounted or when autoGathering state changes.我有一个 React 组件,我想在它安装时创建一个循环,并在它卸载或autoGathering state 更改时停止循环。 Inside the loop, there is an async function so each itineration should wait for the function to finish before moving to the next one.在循环内部,有一个异步 function 所以每次迭代都应该等待 function 完成,然后再移动到下一个。 Everything should stop when Stop button is tapped.当点击Stop按钮时,一切都应该停止。

My current and broken code:我当前和损坏的代码:

const AutoGather = ({autoGathering, stopAutoGather}) => {

    useEffect(() => {
        for (let i = 0; i < 5; i++) {
            if (autoGathering) {
                processAutoGather(i, autoGathering).then(() => {
                    console.log('other ', i)
                })
            } else {
                console.log('stopping')
                break
            }
        }
    }, [])


    // Some async function here, Database operation and probably a setTimeout
    const processAutoGather = async () => {
        return new Promise((resolve, reject) => {
            if (autoGathering) {
                setTimeout(() => {
                    console.log('resolving')
                    return resolve(true)
                }, 1000)
            } else {
                console.log('rejecting')
                return reject(false)
            }
        })
        
    }

    return (
        <Layout style={{flex:1}}>
            <Layout style={{flex:1}}>
                <Layout style={{flex:1, justifyContent:'center', alignItems:'center'}}>
                    <Button style={{borderRadius:20, minWidth:125}} onPress={()=> stopAutoGather()} status='danger' size='small'>Stop Auto Gather</Button>
                </Layout>
            </Layout>
        </Layout>
    )
}

AutoGather.propTypes = {
    autoGathering: PropTypes.bool.isRequired,
    materialToGather: PropTypes.string.isRequired,
    stopAutoGather: PropTypes.func.isRequired
}

export default AutoGather

You probably want to await the gathering to complete before launching the next one.您可能希望在启动下一个聚会之前等待聚会完成。 Also, you need to clean dependencies of useEffect :此外,您需要清理useEffect的依赖项:

// Create a promise and save the `resolve` for using outside it
const AutoGather = ({autoGathering, stopAutoGather}) => {
    React.useEffect(() => {
      let stopTheCount = false;
      (async () => {
        for (let i = 0; i < 5 && !stopTheCount; i++) {
          await processAutoGather(i);
          console.log('other ', i);
        }
      })();

      // Stop the count!
      return () => { stopTheCount = true };
    }, []);

    // Some async function here, Database operation and probably a setTimeout
    const processAutoGather = async (counter) => {
        return autoGathering
          ? new Promise( (resolve) => {
                setTimeout(() => {
                  if(autoGathering) {
                    console.log('resolving')
                    return resolve(true)
                  }
                }, 1000)
            })
          : Promise.resolve()
    }

    return (...)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM