如何在React Native中使用onPress触发器停止setInterval函数

时间:2019-04-27 17:08:32

标签: javascript react-native

我有这个函数,它使用setInterval每秒调用另一个函数:

  startCameraMode = () => {
    setInterval(() => this.takePicture(), 1000)
  }

我想通过clearInterval使用此表达式停止它:

clearInterval(this.startCameraMode)

这里:

<ActionButton.Item useNativeFeedback={false} buttonColor='#1abc9c' title="Stop" onPress={clearInterval(this.startCameraMode)}>
<Icon name="md-done-all" style={styles.actionButtonIcon} />
</ActionButton.Item>

但是,出现此错误:

ActionButton.props.onPress is not a function

如何使用onPress道具停止setInterval的运行?如果这不可能,那么我想知道其他方法来实现这一目标。

整个代码:

import React, {Component} from 'react';
import {StyleSheet, View} from 'react-native'
import { RNCamera } from 'react-native-camera'
import { CameraRoll } from 'react-native'
import AsyncStorage from '@react-native-community/async-storage'
import Permissions from 'react-native-permissions'
import ActionButton from 'react-native-action-button'
import Icon from 'react-native-vector-icons/Ionicons'


const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },

  button: {
    height: 200,

    justifyContent: 'flex-end',
    alignItems: 'center'
  },

  actionButtonIcon: {
    fontSize: 20,
    height: 22,
    color: 'white',
  },

  buttonLeft: {
    marginRight: 100,
    height: 200,
    justifyContent: 'flex-end',
    alignItems: 'center'
  },

});


export default class Cam extends Component {
  constructor() {
    super()
    this.takePicture = this.takePicture.bind(this)
    this.state = {
      interval: 0,
      unit: 'second(s)',
      cameraModeOn: false
    }
  }

  componentDidMount() {
    this.requestStorage()

    getIntervalData = async () => {
      try {
        const value = await AsyncStorage.getItem('interval')
        if(value !== null) {
          let numberDecimalValue = parseFloat(value)
          this.setState({interval: numberDecimalValue})
        }
      } catch(error) {
        alert(error)
      }
    }
    getIntervalData()

    getUnitData = async () => {
      try {
        const value = await AsyncStorage.getItem('unit')
        if(value !== null) {
          this.setState({unit: value})
        }
      } catch(error) {
        alert(error)
      }
    }
    getUnitData()

  }

  requestStorage = async function() {
    Permissions.check('storage').then(response => {
      if (response != 'authorized') {
        Permissions.request('storage')
      }
    })
  }

  takePicture = async function() {
    if (this.camera) {
      const options = { quality: 0.5, base64: true }
      const data = await this.camera.takePictureAsync(options)
      CameraRoll.saveToCameraRoll(data.uri)
    }
  }

  startCameraMode = () => {
    setInterval(() => this.takePicture(), 1000)
  }

  stop

  render() {
    return (
      <View style={styles.container}>

        <RNCamera
          ref={ref => {this.camera = ref}}
          style={{
            flex: 1,
            width: '100%',
            position: 'relative'
          }}
          type={RNCamera.Constants.Type.back}
          androidCameraPermissionOptions={{
            title: 'Permission to use camera',
            message: 'We need your permission to use your camera',
            buttonPositive: 'Ok',
            buttonNegative: 'Cancel',
          }}
          androidRecordAudioPermissionOptions={{
            title: 'Permission to use audio recording',
            message: 'We need your permission to use your audio',
            buttonPositive: 'Ok',
            buttonNegative: 'Cancel',
          }}
        >
        </RNCamera>

        <ActionButton size={80} useNativeFeedback={false} buttonColor="rgba(231,76,60,1)">
          <ActionButton.Item useNativeFeedback={false} buttonColor='#9b59b6' title="Settings" onPress={this.props.switchScreen}>
            <Icon name="md-create" style={styles.actionButtonIcon} />
          </ActionButton.Item>

          <ActionButton.Item useNativeFeedback={false} buttonColor='#1abc9c' title="Stop" onPress={clearInterval(this.startCameraMode)}>
            <Icon name="md-done-all" style={styles.actionButtonIcon} />
          </ActionButton.Item>

          <ActionButton.Item useNativeFeedback={false} buttonColor='#1abc9c' title="Start" onPress={this.startCameraMode}>
            <Icon name="md-done-all" style={styles.actionButtonIcon} />
          </ActionButton.Item>

        </ActionButton>

      </View>
    )
  }
}

2 个答案:

答案 0 :(得分:1)

setInterval函数返回一个指针。

执行以下操作:

startCameraMode = () => {
   this.intervalPointer = setInterval(() => this.takePicture(), 1000)
}
...
onPress={clearInterval(this.intervalPointer)}

答案 1 :(得分:1)

您应该使用setInterval返回的值调用clearInterval。

将startCameraMode编辑为:

startCameraMode = () => {
  this.isTakingPictures = setInterval(() => this.takePicture(), 1000)
}

和按钮:

<ActionButton.Item 
  useNativeFeedback={false} 
  buttonColor='#1abc9c' 
  title="Stop" 
  onPress={
   if(this.isTakingPictures != undefined) { 
     clearInterval(this.isTakingPictures);
     this.isTakingPictures = undefined;
   }
  }>
  <Icon name="md-done-all" style={styles.actionButtonIcon} />
</ActionButton.Item>

在我看来,您还需要注意触发多个startCameraMode,因为多次按下按钮将导致使用setInterval进行多次调度,而清除间隔(如此处所述)将仅清除最后一个。