admin管理员组

文章数量:1290050

I'm trying to create a simple stopwatch timer in React Native and I've created a new ponent called Chrono to handle the clock data(hours, minutes, etc.)

I'm triggering the clock count up on a button press in the following code:

import React, { Component } from 'react';
import { View, Text, TouchableOpacity, AppRegistry, StyleSheet, Alert } from 'react-native';
import Chrono from './app/Chrono.js';

export default class morphX extends Component {
  constructor(props) {
    super(props)
    this.state = {
      randomCounter: 0
    }
    this.chrono = null
  }

  onItemPressed = () => {
    this.chrono.startTimer()
  }

  updateRandomCounter = () => {
    this.setState({
      randomCounter: this.state.randomCounter + 1
    })
  }

  clearCounter = () => {
    this.setState({ 
      randomCounter: 0
    })
  }

  render() {
    return (
      <View style={styles.mainWrapper}>
        <View style={styles.upperWrapper}>
          <Chrono ref = { r => this.chrono = r} />
        </View>
        <View style={styles.bottomWrapper}>
          <View style={styles.initialButtons}>
            <TouchableOpacity
              style={styles.touchableButton}
              text="Let's Start!"
              onPress={() => this.onItemPressed()}>
              <Text style={styles.buttonTexts}>
                Count Up!
              </Text>
            </TouchableOpacity>
            <TouchableOpacity
              style={styles.touchableButton}
              title="RESET!"
              onPress={() => this.clearCounter()}>
              <Text style={styles.buttonTexts}>
                Reset!
              </Text>
            </TouchableOpacity>
          </View>
        </View>
      </View>
    );
  }
}
AppRegistry.registerComponent('morphX', () => morphX);

and the startTimer is implemented in the Chrono.js ponent here:

import React, { Component } from 'react';
import { View, Text, TouchableOpacity, AppRegistry, StyleSheet, Alert } from 'react-native';

class Chrono extends Component {
    constructor(props) {
        super(props)
        this.state = {
            hours: 0,
            minutes: 0,
            seconds: 0
        }
    }

    // Chronometer start function
    startTimer = () => {
        console.log(this)
        this.setTimeout(function() {
            console.log('HeY!')
            this.setState({
                seconds: 1
            })  
        }, 1000);
    }

    // Chronometer pause function 
    pauseTimer = () => {

    }

    // Chronometer reset function 
    resetTimer = () => {

    }

    render() {
        return (
            <View style={styles.clockWrapper}>
                <Text style={styles.hourWrapper}>
                    {this.state.hours}
                </Text>
                <Text style={styles.colonWrapper}>
                    :
                </Text>
                <Text style={styles.minuteWrapper}>
                    {this.state.minutes}
                </Text>
                <Text style={styles.colonWrapper}>
                    :
                </Text>
                <Text style={styles.secondsWrapper}>
                    {this.state.seconds}
                </Text>
            </View>
        )
    }
}

export default Chrono

I'm facing the error

this.setTimeout is not a function

on the line where I'm calling the setTimeout for some reason. Why?

I'm trying to create a simple stopwatch timer in React Native and I've created a new ponent called Chrono to handle the clock data(hours, minutes, etc.)

I'm triggering the clock count up on a button press in the following code:

import React, { Component } from 'react';
import { View, Text, TouchableOpacity, AppRegistry, StyleSheet, Alert } from 'react-native';
import Chrono from './app/Chrono.js';

export default class morphX extends Component {
  constructor(props) {
    super(props)
    this.state = {
      randomCounter: 0
    }
    this.chrono = null
  }

  onItemPressed = () => {
    this.chrono.startTimer()
  }

  updateRandomCounter = () => {
    this.setState({
      randomCounter: this.state.randomCounter + 1
    })
  }

  clearCounter = () => {
    this.setState({ 
      randomCounter: 0
    })
  }

  render() {
    return (
      <View style={styles.mainWrapper}>
        <View style={styles.upperWrapper}>
          <Chrono ref = { r => this.chrono = r} />
        </View>
        <View style={styles.bottomWrapper}>
          <View style={styles.initialButtons}>
            <TouchableOpacity
              style={styles.touchableButton}
              text="Let's Start!"
              onPress={() => this.onItemPressed()}>
              <Text style={styles.buttonTexts}>
                Count Up!
              </Text>
            </TouchableOpacity>
            <TouchableOpacity
              style={styles.touchableButton}
              title="RESET!"
              onPress={() => this.clearCounter()}>
              <Text style={styles.buttonTexts}>
                Reset!
              </Text>
            </TouchableOpacity>
          </View>
        </View>
      </View>
    );
  }
}
AppRegistry.registerComponent('morphX', () => morphX);

and the startTimer is implemented in the Chrono.js ponent here:

import React, { Component } from 'react';
import { View, Text, TouchableOpacity, AppRegistry, StyleSheet, Alert } from 'react-native';

class Chrono extends Component {
    constructor(props) {
        super(props)
        this.state = {
            hours: 0,
            minutes: 0,
            seconds: 0
        }
    }

    // Chronometer start function
    startTimer = () => {
        console.log(this)
        this.setTimeout(function() {
            console.log('HeY!')
            this.setState({
                seconds: 1
            })  
        }, 1000);
    }

    // Chronometer pause function 
    pauseTimer = () => {

    }

    // Chronometer reset function 
    resetTimer = () => {

    }

    render() {
        return (
            <View style={styles.clockWrapper}>
                <Text style={styles.hourWrapper}>
                    {this.state.hours}
                </Text>
                <Text style={styles.colonWrapper}>
                    :
                </Text>
                <Text style={styles.minuteWrapper}>
                    {this.state.minutes}
                </Text>
                <Text style={styles.colonWrapper}>
                    :
                </Text>
                <Text style={styles.secondsWrapper}>
                    {this.state.seconds}
                </Text>
            </View>
        )
    }
}

export default Chrono

I'm facing the error

this.setTimeout is not a function

on the line where I'm calling the setTimeout for some reason. Why?

Share Improve this question edited Sep 10, 2017 at 11:26 T.J. Crowder 1.1m199 gold badges2k silver badges1.9k bronze badges asked Sep 10, 2017 at 11:06 hexpheushexpheus 76110 silver badges23 bronze badges 3
  • 2 @T.J.Crowder React-Native has its own implementation of Timers. – bennygenel Commented Sep 10, 2017 at 11:16
  • 1 @T.J.Crowder react-native usually es with all the capabilities all together. 99% of the topics talked in docs already included, this is one of that isn't. Its pretty understandable for a new user to expect it already included. – bennygenel Commented Sep 10, 2017 at 11:20
  • 1 @bennygenel: I'm shocked to see that the mixin puts it on the ponent itself. Following the link you provide below explains why; without that context, it seems like massive smell. And that explains the OP's question, thanks. – T.J. Crowder Commented Sep 10, 2017 at 11:24
Add a ment  | 

3 Answers 3

Reset to default 4

TimerMixin is not included with the default react-native. You have to install it yourself and then you can use this.setTimeout. Check here for detailed information.

This library does not ship with React Native - in order to use it on your project, you will need to install it with
npm i react-timer-mixin --save
from your project directory.


Keep in mind that if you use ES6 classes for your React ponents there is no built-in API for mixins. To use TimerMixin with ES6 classes, we remend react-mixin.

I'm used setTimeout() without including react-timer-mixin, and its working fine in my application.

ponentDidMount() {

    const a = setTimeout(() => {

      // do some stuff here

    }, 100);

}

setTimeout() is global and actually window.setTimeout() in a browser, in React Native window is implied for global functions that use it. so this.setTimeout() should actually be just setTimeout().

Additionally see setTimeout in React Native that the callback function inside the setTimeout() changes the scope of "this"

本文标签: javascriptthissetTimeout() is not a function React nativeStack Overflow